Sly
Sly

Reputation: 733

Rails: specifying a different database in the model

I'm trying to set up Rails (v3.2.2) to use multiple databases. I'm doing this based on this Connecting Rails 3.1 with Multiple Databases.

My model:

class Category < ActiveRecord::Base                                                                                                                                                                                                                                                                                                
  establish_connection :category_database                                                                                                                                                                                                                                                                                                                       
  self.primary_key = "cat_id"                                                                                                                                                   

  validates_presence_of :name, :display_name, :description, :icon, :image, :parent_category_id, :create_time                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
end

database.yml:

category_database:                                                                                                                                                              
  adapter: mysql2                                                                                                                                                               
  encoding: utf8                                                                                                                                                                
  reconnect: false                                                                                                                                                              
  database: main_cat                                                                                                                                                         
  pool: 5                                                                                                                                                                       
  username: root                                                                                                                                                                
  password: blah                                                                                                                                                                    
  socket: /var/run/mysqld/mysqld.sock

When I run this spec file:

require 'spec_helper'                                                                                                                                                           

describe Category do                                                                                                                                                            
  puts "ENV: #{Rails.env}"                                                                                                                                                      
  it { should validate_presence_of :name }                                                                                                                                      
  it { should validate_presence_of :display_name }                                                                                                                              
  it { should validate_presence_of :description }                                                                                                                               
  it { should validate_presence_of :icon }                                                                                                                                      
  it { should validate_presence_of :image }                                                                                                                                     
  it { should validate_presence_of :parent_category_id }                                                                                                                        
  it { should validate_presence_of :create_time }                                                                                                                               

end            

like this:

>rspec /path/to/category_spec.rb  

I get:

/home/user/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract/connection_specification.rb:45:in `resolve_hash_connection': database configuration does not specify adapter (ActiveRecord::AdapterNotSpecified)

I've also tried setting establish_connection like this:

  establish_connection(                                                                                                                                                         
    :adapter => "mysql2",                                                                                                                                                       
    :encoding => "utf8",                                                                                                                                                        
    :reconnect => false,                                                                                                                                                      
    :database => "main_cat",                                                                                                                                                 
    :pool => 5,                                                                                                                                                                 
    :username => "root",                                                                                                                                                        
    :password => "blah",                                                                                                                                                            
    :socket => "/var/run/mysqld/mysqld.sock")

which results in the same exception. (AdapterNotSpecified)

What's strange is that if I abandon establish_connection altogether and apply the exact same connection configuration via the database.yml file like this:

test:                                                                                                                                                                           
  adapter: mysql2                                                                                                                                                               
  encoding: utf8                                                                                                                                                                
  reconnect: false                                                                                                                                                              
  database: main_cat                                                                                                                                                         
  pool: 5                                                                                                                                                                       
  username: root                                                                                                                                                                
  password: blah                                                                                                                                                                    
  socket: /var/run/mysqld/mysqld.sock   

it works.

It seems that Rails is ignoring establish_connection altogether...am I missing some application-level config setting or something? How do I get Rails to recognize establish_connection so that I can place different models in different databases?

Much appreciated!

Upvotes: 2

Views: 4669

Answers (2)

nichg
nichg

Reputation: 1

I was experiencing the same error for much the same reason, however I did have a test: configuration in my database.yml; but the problem was in my provisioning of the "establish connection" method within the model definition:

  establish_connection 'cm_inv_mgmt_' + Rails.env.downcase

although I provided the sections of database.yml for the production/staging and development environments, I was missing cm_inv_mgmt_test!

Upvotes: 0

Sly
Sly

Reputation: 733

So it turns out that Rails requires the presence of a default configuration. In this case, the database.yml file still requires a test database. Otherwise, Rails will throw an exception as it expects to establish some connection before the models are initialized. Once the default configuration is loaded, Rails goes on later to initialize the models and then model-level database configuration can take place via establish_connection.

I hope this helps someone else out there. It took me a considerable amount of time running the debugger through

activerecord-3.2.2/lib/active_record/connection_adapters/abstract/connection_specification.rb

to figure this out.

Upvotes: 6

Related Questions