Multiple Databases on Rails
Being a tagging freak, I wanted to coalesce my database of tagged tables with typo’s nascent support of tags. Only problem: both use ‘tags’ as the tag table name.
My choices were to either:
- change the name of my tags table and all its joining tables as well as a hefty amount of code I’ve written for those tables
- simply extend typo to connect to two databases.
I chose the latter.
Since I was defining more table classes, I made another model file under app/models/ ( called url.rb for me). I then made sure the controller I was using aware of my model file by giving it a model declaration:
class ArticlesController < ApplicationController
model :article,:url
#all other code
# ...
end
Note that I have to explicitly define the article model which was implicit until I used :model.
So what did I put in my model class?
From reading the rails wiki and the ActiveRecord API I found out that any table class can establish its own database connection via :establish_connection
. So I wrote the following
class MyTags < ActiveRecord::Base
establish_connection({
:adapter => "mysql",
:username => "bozo",
:password => "bogus",
:database => "tags"
})
set_table_name "tags"
end
Soon enough I wanted to have a couple of tables that used my second database. From the ActiveRecord
API, I read that subclasses of a table class share the same connection so I figured I’d make an abstract connection class for all the tag tables. So I tried the following
class TagsDB < ActiveRecord::Base
establish_connection({
:adapter => "mysql",
:username => "bozo",
:password => "bogus",
:database => "tags"
})
end
class MyTags < TagsDB
set_table_name "tags"
end
class Url < TagsDB
end
Wrong, instead I got this error:
ActiveRecord::StatementInvalid (Table ‘tags.tags_a_rs’ doesn’t exist: SHOW FIELDS FROM tags_a_rs)
I was able to get the above code to work only by making the parent class a valid table and redefining the subclasses’ table names. Since it seemed poor design to have tables inherit more than they should (table name, relationships and who knows what else) for a database connection, I reverted to defining the connection for every class:
$tags_connection = {
:adapter => "mysql",
:username => "bozo",
:password => "bogus",
:database => "tags"
}
class MyTags < ActiveRecord::Base
establish_connection $tags_connection
set_table_name "tags"
end
class Url
establish_connection $tags_connection
end
This is the cleanest solution I found from what I understand of subclassing table classes.