Quantcast
Channel: Bit Melt Blog
Viewing all articles
Browse latest Browse all 25

Connecting to Multiple Databases in Ruby on Rails

$
0
0

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.


Viewing all articles
Browse latest Browse all 25

Trending Articles