我运行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
。有什么想法吗?
答案 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)
我创建了一个名为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下我们刚刚使用了一个字符串)。