Re: Changing a model''s database connection

Bob Proulx
Mon, 19 Jul 2010 19:30:10 -0000

Michaël wrote:
> I want to be able to set those models to use a database on a
> different server.
> ...
> I''ve tried the following, but it doesn''t seem to have any
effect:

I do this for switching between a legacy db and a new db.  It works
fine.  But I was doing it a slightly different way and it.

I think the simplest way is to define a new database in your
config/database.yml file.  You should be able to pass in all of the
parameters inline too but that tends not to be DRY as you will almost
certainly need to refer to it more than once.  So having it in one
place in the database.yml is nice and only once.  Something like this:

myotherdb:
  adapter: mysql
  username: myusername
  password: mypassword
  database: myotherdatabase

Then to always use it for a model then refer to it by name using
establish_connection.  Like this:

class User < ActiveRecord::Base
  establish_connection "myotherdb"
  ...
end

Since you only want to change to it sometimes dynamically depending
upon what you are doing then you can call establish_connection inline
and switch over from one db to the other.  Since you are manually
explicitly changing db''s out from under activerecord then
don''t forget
to switch back to the standard one afterward.  Not doing that was a
source of bugs in my own projects.  The symptom was that sometimes,
depending upon the program flow, it would end up talking to the wrong
database.

def build_report
  ActiveRecord::Base.establish_connection("myotherdb") if !
ENV[''RAILS_ENV''] == ''test''
  ... do your other db stuff here ...
  ActiveRecord::Base.establish_connection(ENV["RAILS_ENV"]) if !
ENV[''RAILS_ENV''] == ''test''
end

Note the use of ENV["RAILS_ENV"] to select the right database when
returning.  That assumes that you are using the standard "production"
and "development" names.  Note the avoidance of this switch when
running tests.  Two gotchas that I tripped over when first setting
this up.

Also, an unrelated side remark, ruby isn''t python and you
don''t need
to end lines with colons, as you had done in your example.  :-)

Bob

P.S. Sorry if the thread of this message is broken.  I had a personal
snafu and needed to recreate the message from parts.