The framework Ruby on Rails isn't designed to manage multiple databases at the same time, anyway a wonderful gem Octopus allows to manage multiple dbs in a transparent and clean way
Simple use case: Data DB and Admin DB
Many web applications have accounts, permissions, logging and some data to display. These entities usually belongs to the same db, but if the we need to change often the data structures there is a risk to lose some data during the schema migration or evolution, so a safe and indipendent db perfectly fit for this need.
So let's see how to tweak the Rails MVC to manage different DBs (sharding) at the model level.
# Gemfile # add octopus dependency and *setup your DBs*
gem 'ar-octopus', :require => "octopus", :git => 'https://github.com/tchandy/octopus.git'
Then You need a way to separate the Admin DB migrations from the Data DB migrations.
By default all the migrations will belong to the master DB which is the Data DB and the Admin DB migrations will specify the different DB in this way:
class CreateUsersDevise < ActiveRecord::Migration
create_table(:users) do |t|
The db :admin is the one specified in the shards.yml file
Now the models who don't use the master db have to specify a different connection and a clean way to do it is to extend the ActiveRecord::Base class to hijack the default connection.
# app/models/admin_record.rb # it's generic
require 'active_support/concern'module AdminRecord
connection_proxy.current_shard = :admin # :master otherwise
class User < ActiveRecord::Base
if everything works as expected open a rails console and try to print
The output rapresent the model connection and it should be different. I've found this approch very clean but I had to disable the Rails class caching feature in production and I had to add also the octopus connection to the normal models .
class Post < ActiveRecord::Base
Let me know what You think and if you have better ways to do db sharding with ActiveRecord. I can say it is perfect but it works if the database use the same adapter driver, otherwise You'll encounter this bug.