Rails RSpec与多个数据库

时间:2009-10-07 00:22:13

标签: ruby-on-rails activerecord rspec database-connection

我运行Rails应用程序,我们正在将注册过程拆分为单独的应用程序。注册应用程序有自己独立的数据库(用于CMS和收集潜在客户),但它也需要访问主数据库。使用ActiveRecord::Base.establish_connection时效果非常好。

但是,我希望能够写出一些规格。问题是,每次我的测试运行时,如何在不清除开发数据库的情况下编写规范/测试?如果我在测试模式下进入控制台,很明显测试模式从我的主应用程序挂钩到开发数据库。

这是我的database.yml文件的样子:

development: 
  database: signup_dev

test:
  database: signup_test

main_app_dev: 
  database: main_app_dev

main_app_test: 
  database: main_app_test

基于此文件,我希望establish_connection连接以在开发模式下连接到数据库my_app_dev,并在测试模式下连接my_app_test。有什么想法吗?

4 个答案:

答案 0 :(得分:2)

我们有一个gem,它基本上是连接到我们遗留系统的ActiveRecord模型的集合。在我们的例子中,我们拥有模块中包含的所有模型,所有与遗留数据库相关的模型都与之相连。

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

  class User < Base
  end
end

通过此设置,可以轻松切换数据库连接。如果您真的想要进行自动检测,可以在基类中放置逻辑以确定要使用的数据库:

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

或者只是告诉您的模块在规范助手中使用哪个连接:

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

我个人会推荐第二种选择。当然,这两种解决方案都依赖于命名空间模型。

对等

答案 1 :(得分:1)

Ryan,我们也在从一个数据存储区迁移到另一个数据存储区。我们需要针对两个数据库进行开发,并为每个数据库维护单独的迁移和固定装置。

我创建了一个名为Secondbase的gem来帮助解决这个问题。从本质上讲,它允许您在单个Rails应用程序中无缝管理两个数据库。也许它也会解决您的问题:https://github.com/karledurante/secondbase

答案 2 :(得分:0)

这是我想出的一个混音:

# 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'

为了使这与RSpec一起使用,这需要在初始化程序中加载 - 显然在环境文件中加载它会导致它加载太晚,并且它将无法工作。

答案 3 :(得分:0)

我们刚刚使用插值:

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

有趣的:"main_app_"语法从字符串中生成符号。这也可以写成"main_app_#{Rails.env}".to_sym。在Rails 4.1的任何一种情况下,这必须是一个符号(在3.2下我们刚刚使用了一个字符串)。