Railsで複数データベース使用時のDatabaseCleanerの設定

前回のRailsで複数データベースを扱うに関連して。

Rspecとかでテストを書くときに作成したテストデータを、テストを実行するたびに削除してくれるgemとして、DatabaseCleanerがある。複数データベースを扱う際は、それ毎に設定を記述しなければいけないので、その設定。

例えば、こんなモデルがあるとすると

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

DatabaseCleanerでは、直接modelを指定できるので以下のように書ける。

RSpec.configure do |config|
  ...

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)

    DatabaseCleaner[:active_record,{:model => Hoge}].strategy = :transaction
    DatabaseCleaner[:active_record,{:model => Hoge}].clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.start
    DatabaseCleaner[:active_record,{:model => Hoge}].start
  end

  config.after(:each) do
    DatabaseCleaner.clean

    DatabaseCleaner[:active_record,{:model => Hoge}].clean
  end

  ...

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等が使えるようになる。

参考

Idobata.ioに通知できるRedmineのプラグインを作った

Redmineのチケットを作成/編集、Wikiを更新した際に、Idobata.ioに通知されるプラグインを作った。
Redmineのプロジェクトごとに通知したいルームを指定できる。

https://github.com/kawahiro311/redmine_idobata

f:id:kawahiro311:20140605201110p:plain

きっかけはFukuoka.rbのもくもく会でなんかもくもくするネタないかなーというところから始まって、以前Redmineプラグイン作ったことがあったということもあり、ある程度すぐできた。

普段Idobata.ioとRedmine使っている人にとっては、「Redmine更新したので見て下さい」とかわざわざ伝える必要がなくなって、便利だと思うので是非(・∀・)