Rails RSpec with Multiple Databases

后端 未结 4 905
情书的邮戳
情书的邮戳 2021-01-28 00:05

I run a Rails app, and we\'re in the process of splitting out our signup process to a separate app. The signup app has its own separate database (for CMS and collecting prospect

相关标签:
4条回答
  • 2021-01-28 00:36

    We have a gem that is basically a collection of ActiveRecord models that connect to our legacy system. In our case we have all those models contained in a module from which all models related to the legacy database connects.

    module Legacy
      class Base < ActiveRecord::Base
        establish_connection :legacy
      end
    
      class User < Base
      end
    end
    

    With this setup it makes it really easy to switch out the database connection. If you really go for that automated detection you can put logic in your base class to determine which database to use:

    module Legacy
      class Base < ActiveRecord::Base
        if Rails.env == 'test'
          establish_connection :legacy_test
        else
          establish_connection :legacy
       end
    end
    

    Or simply tell your module which connection to use in your spec helper:

    # spec/spec_helper.rb    
    Legacy::Base.establish_connection(ActiveRecord::Base.configurations['legacy_test'])
    

    Personally I would recommend the second option. Of course both solutions depend on namespaced models.

    Peer

    0 讨论(0)
  • 2021-01-28 00:46

    Ryan, we were also in the process of migrating from one datastore to another. We needed to develop against two databases and maintain separate migrations and fixtures for each.

    I created a gem called Secondbase to help with this. Essentially, it allows you to manage two databases seamlessly in a single Rails app. Perhaps it will solve your issue as well: https://github.com/karledurante/secondbase

    0 讨论(0)
  • 2021-01-28 00:50

    Here's what I came up with as a mixin:

    # lib/establish_connection_to_master_database.rb
    module EstablishConnectionToMasterDatabase
      def establish_connection_to_master_database
    
        case RAILS_ENV
        when "development"
          establish_connection :master_dev
        when "test"
          establish_connection :master_test
        when "production"
          establish_connection :master
        end
    
      end
    end
    ActiveRecord::Base.send(:extend, EstablishConnectionToMasterDatabase)
    
    # models/subscription.rb
    class Subscription < ActiveRecord::Base
      establish_connection_to_master_database
    end
    
    # config/initializers/config.rb
    require 'establish_connection_to_master_database'
    

    In order for this to work with RSpec, this needs to be loaded in an initializer - apparently loading it in the environment file causes it to be loaded it too late, and it won't work.

    0 讨论(0)
  • 2021-01-28 00:54

    We just used interpolation for this:

    class ServiceModel < ActiveRecord::Base
      establish_connection :"main_app_#{Rails.env}"
    end
    

    The funny :"main_app_" syntax makes a symbol from a string. This could be also written "main_app_#{Rails.env}".to_sym. In either case with Rails 4.1 this must be a symbol (under 3.2 we had just used a string).

    0 讨论(0)
提交回复
热议问题