Help us understand the problem. What is going on with this article?

複数のDBに対するマイグレーションのあれこれ

More than 1 year has passed since last update.

railsで複数のデータベースを使いたい時がある。
そんな時は@eagletmtさんが作成したswitch_pointを使うと良い感じになれる。
使い方などはGitHubのドキュメントを見れば何も困らない。

本題はこっから
例えばメインをmysqlにして2つ目をpostgresqlなどにした場合にpostgresql側のマイグレーションどうしようってなる。
ちなみにdatabase.ymlはこんな感じ

database.yml
・・・
development_postgresql:
  adapter: postgresql
  host: localhost
  database: hogehoge
  username: postgres
  password: 
  pool: 5
  timeout: 5000

シンプルなパターン

どちらもスキーマが一緒でmigrationの設定などを共有して使用する時

完成系

$ RAILS_ENV=development_postgresql rake db:create
$ RAILS_ENV=development_postgresql rake db:migrate

解説

  • rake db:createを定義している所を見てみるActiveRecord::Tasks::DatabaseTasks.create_currentってのを呼んでるっぽい
  • ActiveRecord::Tasks::DatabaseTasks.create_currentの呼び出し元はここ
  • そして一番のポイントとなるのがここ
    • ここでRAILS_ENVに応じたdatabase.ymlの設定を呼んでるっぽい

ちょっとややこしいパターン

ことなるスキーマでマイグレーションファイルも違うのを使用したい時など
ちょっとややこしいことをする時はtaskを書いてあげる。

完成系

psql.rake
namespace :psql do
  DEFAULT_DB_CONF = 'development_postgresql'
  DEFAULT_ENV = 'development'

  task :load_config do
    db_conf = ENV['PSQL_DB_CONF'] ||= DEFAULT_DB_CONF
    env = ENV['RAILS_ENV'] ||= DEFAULT_ENV
    ActiveRecord::Base.configurations = {env => ActiveRecord::Base.configurations[db_conf]}

    # migrationを変えたいときはこれに代入する。 default: [db/migrate]
    # ActiveRecord::Migrator.migrations_paths = ["#{Rails.root}/db/hoge_migrate"]
  end

  # データベース作成
  task create_db: :load_config do
    ActiveRecord::Tasks::DatabaseTasks.create_current
  end

  # マイグレーション
  task migrate: [:environment, :load_config] do
    ActiveRecord::Tasks::DatabaseTasks.migrate
  end

end

解説

参考にするのはrake db:createなどを呼び出した時に呼ばれるdatabases.rake
メインはload_configタスク。
動きとしてはdb_confにdatabase.ymlのどの設定を取り出すかを指定。
後はRAILS_ENVに応じて設定が読まれるのでdatabase.ymlのhashをRAILS_ENVに応じて作成してActiveRecord::Base.configurationsにいれるだけ。

よく「rails 複数のDB migrate」と検索するとRails.application.config.pathsにschemaの場所とかdatabase.ymlの場所を指定してるけど、今回switch_pointで1つのdatabase.ymlにいれているので、ymlファイルをわけたくなかったため、こんな実装になっている。

最適な解ではないかもしれないけど。。。

やってみて

とりあえずドキュメント読めばなんとかなる。
ただとりあえずなのでRails Wayに乗れていない感があるのでもっとスマートなやり方があったら教えてほしい

hatappi
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away