More Advanced Database Features and Rails - Connecting to Multiple Databases (Page 2 of 4 )
Occasionally, you will have the need to connect to several different databases from one application. This is useful for migrating from an old schema to a new one. It is also helpful if you have differing data requirements within one application; perhaps some data is more critical and is stored on a high-availability database cluster. In any case, it is easy in Rails. First, specify multiple database environments in the database.yml configuration file:
legacy: adapter: mysql database: my_db username: user password: pass host: legacy_host
new: adapter: mysql database: my_db username: user password: pass host: new_host
Then, you can simply refer to these configuration blocks from the ActiveRecord class definition using the ActiveRecord::Base.establish_connection method:
class LegacyClient < ActiveRecord::Base establish_connection "legacy" end
class Client < ActiveRecord::Base establish_connection "new" end
This approach also works with multiple Rails environments. Just specify each environment in the database.yml file as usual:
legacy_development: # ...
legacy_test: # ...
legacy_production: # ...
new_development: # ...
new_test: # ...
new_production: # ...
Then, use the RAILS_ENV constant in the database configuration block name:
class LegacyClient < ActiveRecord::Base stablish_connection "legacy_#{RAILS_ENV}" end
class Client < ActiveRecord::Base establish_connection "new_#{RAILS_ENV}" end
You can go one step further and DRY this code up by using class inheritance to define which database an ActiveRecord class belongs to:
class LegacyDb < ActiveRecord::Base self.abstract_class = true establish_connection "legacy_#{RAILS_ENV}" end
class NewDb < ActiveRecord::Base self.abstract_class = true establish_connection "new_#{RAILS_ENV}" end
class LegacyClient < LegacyDb end
class Client < NewDb end
The self.abstract_class = true statements tell ActiveRecord that the LegacyDb and NewDb classes cannot be instantiated themselves; since they represent database connections, they are not backed by concrete tables in the database.