Firstly, we need to define the external database:
# config/database.yml
external:
adapter: sqlite3
database: db/external.sqlite3
pool: 5
timeout: 5000
For something like this, I prefer using a module that takes care of database connections.
# lib/database.rb
module Database
def self.using(db, klass=ActiveRecord::Base)
klass.establish_connection(db.to_sym)
result = yield if block_given?
klass.establish_connection(Rails.env.to_sym)
result
end
end
By passing a block to a module like this we can make sure we don't bleed our queries into a database where they don't belong or forget to revert our connection. Also, we default to ActiveRecord::Base so that we can work with any of our models. However, if we know we're only using one and want to isolate our model usage, we can pass it as the secondary parameter.
The resulting implementation can look something like this:
# app/models/user.rb
class User < ActiveRecord::Base
def read_remote
Database.using(:external) do
account = Account.where(active: true)
account.users
end
end
end
Now we have a nice and clean block we can use anywhere we like, use any models we want inside the block and always be operating on the extneral database. Once that block is finished, we know we're working back on our original database.