If you keep different tables in different databases, you've probably been looking for a way to allow Rails to connect to more than one database. You've probably found that you can add another configuration (besides development
, test
and production
) to config/database.yml
. There's a problem with that though. If you added a configuration called foo
, you are now always connecting to foo
, in production mode, test mode and development mode. This is especially bad in test mode, since the database would get wiped, but you probably want a different database for development and production too.
Here's how to do it. Suppose you have already set up your regular development/test/production databases in config/database.yml
:
development: adapter: jdbc driver: com.mysql.jdbc.Driver url: jdbc:mysql://devdb.yourdomain.com:3306/mstore username: cart password: secret # Warning: The database defined as 'test' will be erased and # re-generated from your development database when you run 'rake'. # Do not set this db to the same as development or production. test: adapter: jdbc driver: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/mstore username: cart password: secret production: adapter: jdbc driver: com.mysql.jdbc.Driver url: jdbc:mysql://proddb.yourdomain.com:3306/mstore username: cart password: secret
Now you decided to store all the user account information in a different database. You still want a separate development, test and production databases for your account information. You'll need to add three more entries to the database configuration then, one for each of the account databases. You'll need to name them with an appropriate suffix to specify development/test/production:
account_development: adapter: jdbc driver: com.mysql.jdbc.Driver url: jdbc:mysql://devdb.yourdomain.com:3306/account username: cart password: secret # Warning: The database defined as 'test' will be erased and # re-generated from your development database when you run 'rake'. # Do not set this db to the same as development or production. account_test: adapter: jdbc driver: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/account username: cart password: secret account_production: adapter: jdbc driver: com.mysql.jdbc.Driver url: jdbc:mysql://accountdb.yourdomain.com:3306/account username: cart password: secret
Note that these account databases could be on the same hosts or on different hosts from the main databases. Now on to the models. You need to create a base class model for all your account tables, so that only one connection to the account database gets created. If you just call establish_connection
in every model, it'll open that many database connections, one for each model. Here's a base model for the account tables:
class AccountBase < ActiveRecord::Base # No corresponding table in the DB. self.abstract_class = true # Open a connection to the appropriate database depending # on what RAILS_ENV is set to. establish_connection("account_#{RAILS_ENV}") end
Now your account models need to inherit from AccountBase
instead of ActiveRecord::Base
, like this:
class Login < AccountBase end
Because it inherits from AccountBase
, it'll use the database connection already established by AccountBase
.