Question

I need to use different database connections in different Rails models. Is there a not-so-hacky way to do that?

Any links or search keywords would be great :)

Was it helpful?

Solution

mikej is right. I did however write a gem that makes the model code to connect a little bit cleaner, check it out.

OTHER TIPS

Add new sections to your database.yml e.g.

other_development:
  adapter: mysql
  database: otherdb_development
  username: root
  password:
  host: localhost

other_production:
  adapter: mysql
  database: otherdb_production
  username: root
  password:
  host: localhost

Add a class in lib/other_database.rb

class OtherDatabase < ActiveRecord::Base
  establish_connection "other_#{RAILS_ENV}"
end

and then for each model which isn't in the default database subclass from OtherDatabase e.g.:

class MyModel < OtherDatabase
   # my model code...
end

I have been using the following to connect to 2 db in the same app. I put them in lib folder since everything in there is loaded.

require 'active_record'

class OldDatabase < ActiveRecord::Base
  self.abstract_class = true
  establish_connection(
  :adapter  => 'mysql',
  :database => 'weather',
  :host     => 'localhost',
  :username => 'root',
  :password => 'password'
  )
end

class NewDatabase < ActiveRecord::Base
  self.abstract_class = true
  establish_connection(
  :adapter  => 'mysql',
  :database => 'redmine',
  :host     => 'localhost',
  :username => 'root',
  :password => 'password'
  )
end

class WeatherData < OldDatabase
end

class Board < NewDatabase
end

Hope that helps

Update for Rails 3.x:

class MyModel < ActiveRecord::Base
  establish_connection "other_#{Rails.env}"
end

I think that the prettiest way to connect to another database with active model is creating base class for external database, and then inherite from that base in your model. This method works fine with rails 4.2.6 and 5.0.4

For example:

# in /models/external_db/base.rb
require 'active_record'

class ExternalDb::Base < ActiveRecord::Base
  self.abstract_class = true
  establish_connection "external_db_#{Rails.env}".to_sym
end

And in your model class:

# in /models/external_db/some_model.rb
class ExternalDB::SomeModel < ExternalDb::Base
  # your code
end

But you must define external database in /config/database.yml

# in /config/database.yml
external_db_development:
  adapter: sqlite3
  pool: 5
  timeout: 5000
  database: db/external_db_development.db

external_db_production:
  adapter: sqlite3
  pool: 5
  timeout: 5000
  database: db/external_db_production.db

In rails 4.1+ establish_connection now takes a symbol:

class OtherDbModel < ActiveRecord::Base
  establish_connection :"other_#{Rails.env}"
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow