Is it possible for ActiveRecord and DatabaseCleaner to deal with two different databases during tests?
Some of my models are related to the Rails “default” database. Some other models are related to an external database which I do not manage. I have access to a Replica and all I do is read from it.
I was able to get this working using the establish_connection
method from ActiveRecord, and providing a different connection for this model.
This worked fine on development and production environments. But I was having problems on the test environment.
For testing, I set up a no-data dump of the database and provided its connection to Rails.
module MultipleDatabasesExtension
extend ActiveSupport::Concern
# add your static(class) methods here
module ClassMethods
def establish_connection_to database_hash
if Rails.env.test?
establish_connection database_hash[:test]
elsif Rails.env.development?
establish_connection database_hash[:development]
elsif Rails.env.production?
establish_connection database_hash[:production]
else
establish_connection database_hash[:production]
end
end
end
end
# include the extension
ActiveRecord::Base.send(:include, MultipleDatabasesExtension)
After that I used
establish_connection_to({
test: :replica_test,
development: ENV['REPLICA_DATABASE_URL'],
production: ENV['REPLICA_DATABASE_URL']
})
self.table_name = 'answers'
So it would select the correct database. I was trying to manage the database using:
db_config = ActiveRecord::Base.configurations["replica_test"]
ActiveRecord::Tasks::MySQLDatabaseTasks.new(db_config).structure_load("db/replica.sql")
So it would reload the database from the replica.sql file.
At this point, I can clean the database when by running the two commands above (I can make them a rake task). However I want to automate this by using DatabaseCleaner to correctly prepare the database for each test.
When I used the following excerpt:
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.clean_with(:deletion)
DatabaseCleaner[:active_record,{:connection => :replica_test}].clean_with(:deletion)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner[:active_record,{:connection => :replica_test}].strategy = :transaction
end
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :deletion
DatabaseCleaner[:active_record,{:connection => :replica_test}].strategy = :deletion
end
config.before(:each) do
DatabaseCleaner.start
DatabaseCleaner[:active_record,{:connection => :replica_test}].start
end
config.after(:each) do
DatabaseCleaner.clean
DatabaseCleaner[:active_record,{:connection => :replica_test}].clean
end
end
and runned rake, it erased all my replica database on production!! What may happened? The connection clearly show a test database.
So, now I’m not sure what path to follow. Have you guys ever dealt with a multiple database like this? i.e., where one of them doesn’t live inside the app?
What’s the best strategy to configure it?