Connecting Rails 3.1 With Multiple Databases

Connecting Rails 3.1 with Multiple Databases

To Wukerplank's answer, you can also put the connection details in database.yml like usual with a name like so:

log_database_production:
adapter: mysql
host: other_host
username: logmein
password: supersecret
database: logs

Then in your special model:

class AccessLog < ActiveRecord::Base
establish_connection "log_database_#{Rails.env}".to_sym
end

To keep those pesky credentials from being in your application code.

Edit: If you want to reuse this connection in multiple models, you should create a new abstract class and inherit from it, because connections are tightly coupled to classes (as explained here, here, and here), and new connections will be created for each class.

If that is the case, set things up like so:

class LogDatabase < ActiveRecord::Base
self.abstract_class = true
establish_connection "log_database_#{Rails.env}".to_sym
end

class AccessLog < LogDatabase
end

class CheckoutLog < LogDatabase
end

How to use multiple databases for one rails 3.1 app in Heroku?

Regarding Neil's answer, here is a way to do it. Not an out-of-box solution, but might give you an idea...
/lib/active_record_extensions.rb

module ActiveRecordExtensions
class Shard < ActiveRecord::Base
#need to switch to the shard database connection from heroku config
primary_database_url = ENV['PRIMARY_DATABASE_URL']

if(!primary_database_url.nil?)
parsed_connection_string = primary_database_url.split("://")
adapter = parsed_connection_string[0]
parsed_connection_string = parsed_connection_string[1].split(":")
username = parsed_connection_string[0]
parsed_connection_string = parsed_connection_string[1].split("@")
password = parsed_connection_string[0]
parsed_connection_string = parsed_connection_string[1].split("/")
host = parsed_connection_string[0]
database = parsed_connection_string[1]

establish_connection(
:adapter => adapter,
:host => host,
:username => username,
:password => password,
:database => database,
:port => 3306,
:pool => 5,
:timeout => 5000
)
else
self.establish_connection "shard_#{Rails.env}"
end
end

class ShardMigration < ActiveRecord::Migration
def connection
ActiveRecord::Shard.connection
end
end
end

So your model should just extend ActiveRecord::Shard instead of Base

How to access multiple databases in rails 3.1.0 app?

You should be able to use ActiveRecord::Base.establish_connection to dynamically connect to any database you like within a certain context. How you implement this is entirely application-specific, but Rails does have this capability.

Here's a very contrived example:

class User
def books
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => self.username,
:password => self.password,
:database => self.database
)

Book.all
rescue Exception => e
# ...
end
end

You would want to do actual error handling and probably establish the connection somewhere outside of an instance method, but that's up to you to decide.

Using ActiveRecord on Multiple Databases

You can use ActiveRecord::Base#establish_connection, to connect to the desired database.

You could pass the db credentials to establish_connection as a Hash

establish_connection(
adapter: 'mysql2',
encoding: 'utf8',
pool: 5,
username: 'me',
password: 'mypassword'
)

There are more examples here

Multiple databases in Rails

You should not do that on Application Layer.

Use keepalived or Amazon RDS.



Related Topics



Leave a reply



Submit