Railsで複数データベースを扱う

案件で複数データベースの使用が必要になったので、いろいろやり方を調べて自分なりにまとまってきたのでメモ。

接続先の情報をconfig/database2.ymlファイルを新規作成して記述

# 2つめのデータベースの設定

development:
  adapter: postgresql
  encoding: unicode
  database: hoge_development
  pool: 5
  username: postgres
  password:

test:
  adapter: postgresql
  encoding: unicode
  database: hoge_test
  pool: 5
  username: postgres
  password:

production:
  adapter: postgresql
  encoding: unicode
  database: hoge_production
  pool: 5
  username: postgres
  password: 

モデルから2つめのデータベースに接続する

class Hoge < ActiveRecord::Base
  database = YAML::load(IO.read('config/database2.yml'))
  establish_connection(database[Rails.env])
end

2つめのデータベースで複数テーブルを扱う場合、それぞれのモデルでestablish_connectionをすると、モデル毎にコネクションをはってしまう。
なので抽象クラスを作成して、それを継承するのが良い。

class Hoge < ActiveRecord::Base
  self.abstract_class = true

  database = YAML::load(IO.read('config/database2.yml'))
  establish_connection(database[Rails.env])
end
class Fuga < Hoge
end

2つ目のデータベース用rakeタスクを作成

# database2.rake

namespace :db2 do
  desc "hoge db configuration"
  task :set_db_config do
    ENV['SCHEMA'] = 'db2/schema.rb'
    Rails.application.config.paths['db'] = ['db2']
    Rails.application.config.paths['db/migrate'] = ['db2/migrate']
    Rails.application.config.paths['db/seeds'] = ['db2/seeds.rb']
    Rails.application.config.paths['config/database'] = ['config/database2.yml']
  end

  task drop: :set_db_config do
    Rake::Task['db:drop'].invoke
  end

  task create: :set_db_config do
    Rake::Task['db:create'].invoke
  end

  task migrate: :set_db_config do
    Rake::Task['db:migrate'].invoke
  end

  task rollback: :set_db_config do
    Rake::Task['db:rollback'].invoke
  end

  task seed: :set_db_config_paths do
    Rake::Task['db:seed'].invoke
  end

  task version: :set_db_config do
    Rake::Task['db:version'].invoke
  end
end

これでrake db2:migraterake db2:create等が使えるようになる。

参考