views:

152

answers:

3

I have a separate DB for one model in my application and in development mode the connection is working properly, in production however it isn't.

production:
  adapter: mysql
  host: myhost
  username: root
  password:
  database: production_db

users_production:
  adapter: mysql
  host: myhost
  username: root
  password:
  database: other_db

The model that connects to the other database is called User but the table it references in other_db is smf_users so my User.rb looks like this:

class User < ActiveRecord::Base
  establish_connection "users_#{RAILS_ENV}"
  set_table_name "smf_users"
end

In production I'm getting this error:

Mysql::Error: Table 'production_db. smf_users' doesn't exist:

Note how it is trying to connect to the wrong database and so isn't finding the correct table. As I say, this works in development mode.

Any suggestions?

A: 

Try:

establish_connection configurations[RAILS_ENV]["users_#{RAILS_ENV}"]
User.connection

establish_connection needs a hash of the connection information. This should return if from database.yml.

You might want to check your log for a message like the following:

"users_production database is not configured"

That message would be thrown by ActiveRecord::Base if it can't find the congifuration by string in database.yml.

catalpa
Thanks, but I'm confident it's finding the config as I don't see that error. I'm pretty sure it's got something to do with ActiveRecord caching the connection.
arfon
have you tried running configurations['users_production'] in a production console to confirm it's accesible?
catalpa
This is very strange. It works fine in the console if I type User.connection but when running through Passenger it hits up the wrong DB
arfon
So basically the settings work fine in a production console but don't work when running through the controllers (i.e. via a web connection). Is it possible that the connection is being cached incorrectly when running through a web server?
arfon
You may need to reset the connection after making the configuration call. I've updated above.
catalpa
The models all inherit from ActiveRecord::Base and share a mutual connection. The User model must clear itself from that shared connection. Which as mentioned as you mentioned, may have to be forced since caching values in a production environment hold on to that connection info. In essence, any call to find_by is going to use the existing connection unless explicitly told otherwise. Try calling connection directly within the model or prior to your finder.
catalpa
Thanks but this still isn't working. Again, in the console there's no problem but through a web server no good.Tried putting User.connection in too...
arfon
A: 

You might find this useful: http://magicmodels.rubyforge.org/magic_multi_connections/

Fer
+1  A: 

I've found when using multiple databases that odd errors show up when doing associations. Any chance you've got another model out there which belongs_to :users and you're expecting it to Just Work? Otherwise, you have to look at caching -- it's easily possible that Rails is failing to cache the connection data for your extra database correctly.

austinfromboston
Yes, that could be it. Will the belongs_to :user fail in this case?
arfon
I think it would, and that would produce the error you're inquiring about. I don't think you'll be able to use the associations DSL across multiple databases. You can create your own :users method on the associated model, and within it say: User.all :conditions => [ 'associated_id = ?', id ]. Another option might be to mirror your User table into the other database using after_save callbacks.
austinfromboston
Yep OK, fair enough.
arfon