Robby on Rails: Multiple Database Connections in Ruby on Railsthoughts.sort_by{|t| t[:topic]}.collect tag:www.robbyonrails.com,2005:TypoTypo2007-10-05T17:55:28-04:00Robby Russellurn:uuid:69a8625d-e24b-4f4e-aa58-d69a677846982007-10-05T17:54:00-04:002007-10-05T17:55:28-04:00Multiple Database Connections in Ruby on Rails<p>We have a client that already has some database replication going on in their deployment and needed to have most of their Ruby on Rails application pull from slave servers, but the few writes would go to the master, which would then end up in their slaves.</p>
<p>So, I was able to quickly extend ActiveRecord with just <em>two</em> methods to achieve this. Anyhow, earlier today, someone in #caboose asked if there was any solutions to this and it prompted me to finally package this up into a quick and dirty Rails plugin.</p>
<p>Introducing… <strong>Active Delegate</strong>!</p>
<p>To install, do the following:</p>
<pre><code>
cd vendor/plugins;
piston import http://svn.planetargon.org/rails/plugins/active_delegate
</code></pre>
<p>Next, you’ll need to create another database entry in your <code>database.yml</code>.</p>
<pre><code>
login: &login
adapter: postgresql
host: localhost
port: 5432
development:
database: rubyurl_development
<<: *login
test:
database: rubyurl_test
<<: *login
production:
database: rubyurl_servant
<<: *login
# NOTICE THE NEXT ENTRY/KEY
master_database:
database: rubyurl_master
<<: *login
</code></pre>
<p>At this point, your Rails application won’t talk to the <code>master_database</code>, because nothing is being told to connect to it. So, the current solution with Active Delegate is to create an ActiveRecord model that will act as a connection handler.</p>
<pre><code>
# app/models/master_database.rb
class MasterDatabase < ActiveRecord::Base
handles_connection_for :master_database # <-- this matches the key from our database.yml
end
</code></pre>
<p>Now, in the model(s) that we’ll want to have talk to this database, we’ll do add the following.</p>
<pre><code>
# app/models/animal.rb
class Animal < ActiveRecord::Base
delegates_connection_to :master_database, :on => [:create, :save, :destroy]
end
</code></pre>
<p>Now, when your application performs a <code>create</code>, <code>save</code>, or <code>destroy</code>, it’ll talk to the master database and your <code>find</code> calls will retrieve data from your servant database.</p>
<p>It’s late on a Friday afternoon and I felt compelled to toss this up for everyone. I think that this could be improved quite a bit, but it’s working great for the original problem that needed to be solved.</p>
<p>If you have feedback and/or bugs, please <a href="http://planetargon.lighthouseapp.com/projects/5187-open-source-projects/">send us tickets</a>.</p><p>We have a client that already has some database replication going on in their deployment and needed to have most of their Ruby on Rails application pull from slave servers, but the few writes would go to the master, which would then end up in their slaves.</p>
<p>So, I was able to quickly extend ActiveRecord with just <em>two</em> methods to achieve this. Anyhow, earlier today, someone in #caboose asked if there was any solutions to this and it prompted me to finally package this up into a quick and dirty Rails plugin.</p>
<p>Introducing… <strong>Active Delegate</strong>!</p>
<p>To install, do the following:</p>
<pre><code>
cd vendor/plugins;
piston import http://svn.planetargon.org/rails/plugins/active_delegate
</code></pre>
<p>Next, you’ll need to create another database entry in your <code>database.yml</code>.</p>
<pre><code>
login: &login
adapter: postgresql
host: localhost
port: 5432
development:
database: rubyurl_development
<<: *login
test:
database: rubyurl_test
<<: *login
production:
database: rubyurl_servant
<<: *login
# NOTICE THE NEXT ENTRY/KEY
master_database:
database: rubyurl_master
<<: *login
</code></pre>
<p>At this point, your Rails application won’t talk to the <code>master_database</code>, because nothing is being told to connect to it. So, the current solution with Active Delegate is to create an ActiveRecord model that will act as a connection handler.</p>
<pre><code>
# app/models/master_database.rb
class MasterDatabase < ActiveRecord::Base
handles_connection_for :master_database # <-- this matches the key from our database.yml
end
</code></pre>
<p>Now, in the model(s) that we’ll want to have talk to this database, we’ll do add the following.</p>
<pre><code>
# app/models/animal.rb
class Animal < ActiveRecord::Base
delegates_connection_to :master_database, :on => [:create, :save, :destroy]
end
</code></pre>
<p>Now, when your application performs a <code>create</code>, <code>save</code>, or <code>destroy</code>, it’ll talk to the master database and your <code>find</code> calls will retrieve data from your servant database.</p>
<p>It’s late on a Friday afternoon and I felt compelled to toss this up for everyone. I think that this could be improved quite a bit, but it’s working great for the original problem that needed to be solved.</p>
<p>If you have feedback and/or bugs, please <a href="http://planetargon.lighthouseapp.com/projects/5187-open-source-projects/">send us tickets</a>.</p>