Rails has never played nice with using multiple databases. While it is very easy to go and set up a new connection via
the niceties that rails provides just don't exist for your second database. Fixtures don't work without explicitly calling
set_fixture_class and you do not have
access to any of the database tasks or generators that are provided by rails. To help alleviate this pain point for us at CustomInk, Karle Durante wrote SecondBase
five years ago to provide database task support and migration generation to Rails applications. Between then and now the internals of Rails changed significantly.
DatabaseTasks took over much of the responsibility for the rake tasks we come to depend on for managing databases. While this refactor is a nice addition.
It required changing the internals of Secondbase to support newer versions of Rails. To this end, Ken Collins and I set out to upgrade and modernize SecondBase.
The solution we settled on is to wrap and enhance the existing Rails database tasks and subclass the migration generator. This provides us with almost all of the tools that
Rails gives the original database in a somewhat future proof fashion and does what Ken alluded to in his Multi-Database practices article.
In your Gemfile add the SecondBase gem:
Then in your
config/database.yml add your SecondBase configuration:
secondbase: development: adapter: mysql database: myapp_development test: adapter: mysql database: myapp_test
This configuration block supports any options that your regular database supports including
Now any model that inherits from
SecondBase::Base will connect to and use the database like a regular ActiveRecord model. You can also use associations between your primary database's
and secondary database's models.
SecondBase enhances key rake tasks to make having two databases as seamless as possible. All create, drop, purge and test tasks will run across both databases by invoking the original.
The only time you will need to call a
db:second_base namespace task is to run a migration on the secondary database exclusively.
Rails' migration generator is subclassed to provide the same features as the original. Simply invoke
second_base:migration and a new migration will be created targeting your
We provide a
SecondBase::Forced helper to allow you to force a class that inherits from ActiveRecord::Base to use your secondary database.
ActiveRecord::SessionStore::Session.extend SecondBase::Forced will make
SessionStore use your secondary database.
We also provide a
Secondbase.on_base helper for situations where you need to temporarily force ActiveRecord::Base to be your secondary database.
The helper is used internally by SecondBase to help deal with the global mutable state issues the migrator and database task objects suffer from.
For instance, you can combo this with DatabaseCleaner's truncation strategy to clean out your database for each test.
I've provided a brief overview of SecondBase here. For a longer explanation of the features provided check out the readme. If you would like to see a demo of this gem in action, check out this demo project. To get a better understanding of multi-database rails applications, I would recommend you check out this post by Ken Collins. Finally, if your still running into issues with any of this, please feel free to open an issue on the SecondBase repo.