How to use multiple databases for one rails 3.1 app in Heroku?
Working off of the previous responses, but incorporating some Rails 3 advantages with the configuration and simplifying the parsing...
# config/application.rbmodule MyApp class Application < Rails::Application ... other configs config.secondary_database_url = ENV['SECONDARY_DB_URL'] endend
We may want to override this in development / test
# config/environments/development.rbmodule MyApp class Application < Rails::Application ... other configs config.secondary_database_url = 'SOME_CONNECTION_STRING' endend
Now to setup the class we'll have our models inherit from...
# lib/active_record/secondary.rb module ActiveRecord class Secondary < ActiveRecord::Base self.abstract_class = true # prior to AR 3.2.1 url = URI.parse( MyApp::Application.config.secondary_database_url ) establish_connection( :adapter => 'mysql', :host => url.host, :username => url.userinfo.split(':')[0], :password => url.userinfo.split(':')[1], :database => url.path[1..-1], :port => url.port || 3306 ) # as of AR 3.2.1 establish_connection(MyApp::Application.config.secondary_database_url) end class SecondaryMigration < ActiveRecord::Migration def connection ActiveRecord::Secondary.connection end endend
Heroku will always connect your app to the production DB that they create for you. If you want to make an additional connection you'll need to do this in your code manually, and create a ENV var that the code can use as a connection string.
Anything in the production segment of database.yml is binned by Heroku and replaced.
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 endend
So your model should just extend ActiveRecord::Shard instead of Base