If you can control and configure each instance of Rails, and you can afford to spend resources because they are in standby mode, save some problems and just change database.yml to change the database connection used for each instance . If you are concerned about performance, this approach will not reduce it.
For models bound to one unique table on only one database, you can call connection_connection inside the model:
establish_connection "database_name_#{RAILS_ENV}"
As described here: http://apidock.com/rails/ActiveRecord/Base/establish_connection/class
You will have some models using tables from one database and other models using tables from other databases.
If you have the same tables, common to different databases and shared by one model, ActiveRecord will not help you. Back in 2009, I needed this in a project that I was working on using Rails 2.3.8. I had a database for each client, and I named the databases with their identifiers. Therefore, I created a method to change the connection inside the ApplicationController:
def change_database database_id = params[:company_id] return if database_id.blank? configuration = ActiveRecord::Base.connection.instance_eval { @config }.clone configuration[:database] = "database_name_#{database_id}_#{RAILS_ENV}" MultipleDatabaseModel.establish_connection configuration end
And added this method as before_filter to all controllers:
before_filter :change_database
So, for each action of each controller, when params [: company_id] is defined and set, it will change the database to the correct one.
To handle migrations, I extended ActiveRecord :: Migration with a method that searches for all clients and iterates the block with each ID:
class ActiveRecord::Migration def self.using_databases *args configuration = ActiveRecord::Base.connection.instance_eval { @config } former_database = configuration[:database] companies = args.blank? ? Company.all : Company.find(args) companies.each do |company| configuration[:database] = "database_name_#{company[:id]}_#{RAILS_ENV}" ActiveRecord::Base.establish_connection configuration yield self end configuration[:database] = former_database ActiveRecord::Base.establish_connection configuration end end
Note that by doing this, it would be impossible to make queries within the same action from two different databases. You can call change_database again, but it will be frustrating when you try to use methods that execute queries from objects that are no longer associated with the correct database. In addition, it is obvious that you will not be able to join tables that belong to different databases.
To handle this, ActiveRecord needs to be greatly expanded. At the moment, there should be a plugin that will help you in solving this problem. A quick study gave me the following:
DB-Charmer: http://kovyrin.github.com/db-charmer/
I am ready to try. Let me know what works for you.