こんにちは、鈴木です。
Ruby on Rails で複数のデータベースを扱う方法をご紹介します。
establish_connection
establish_connection はデータベースと接続するためのメソッドです。
通常は明示的に呼び出すことはありませんが、複数のデータベースを使用する場合は、以下のように明示的に呼び出す必要があります。
1 2 3 4 5 6 7 8 9 10 11 |
class User < ActiveRecord::Base establish_connection :adapter => 'postgresql', :encoding => 'unicode', :database => 'other_database', :pool => '5', :username => 'USERNAME', :password => 'PASSWORD', :host => 'localhost' end |
引数に指定できるオプションは、config/database.yml で指定する内容と同じです。
接続先の情報を database.yml に書いておく
config/database.yml の内容が以下のようになっているとします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
development: ... other_database: adapter: postgresql encoding: unicode database: other_database pool: 5 username: USERNAME password: PASSWORD host: localhost test: ... production: ... |
other_database の部分だけしっかり書いている理由は、これからそこに接続するからです。
それでは接続してみましょう。
1 2 3 4 5 |
class User < ActiveRecord::Base establish_connection :other_database end |
ここでのポイントは、establish_connection の引数に :other_database というシンボルを渡しているところです。
establish_connection は引数に文字列やシンボルが渡された場合、config/database.yml の内容を参照します。
実際にこの方式を利用する場合は :other_database のような決め打ちではなく、「development_other_database」や「test_other_database」のように環境ごとに定義しておき、「establish_connection "#{Rails.env}_other_database"」のように参照することになるでしょう。
同じモデルでも状況によって接続先データベースが異なる場合
同じモデルでも状況によって接続先データベースが異なる場合は、以下のようにモデルクラスの外から establish_connection を呼び出します。
1 2 3 4 5 6 7 |
User.establish_connection :adapter => 'postgresql', :encoding => 'unicode', :database => 'other_database', :pool => '5', :username => 'USERNAME', :password => 'PASSWORD', :host => 'localhost' |
この方式は、システムのユーザごとに参照先データベースやスキーマが異なる場合に使用します。
データベースの接続情報はサブクラスに引き継がれる
データベースの接続情報はサブクラスに引き継がれます。
具体例として、以下のコードを見てください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class TaroDatabaseModel < ActiveRecord::Base self.abstract_class = true establish_connection :taro_database end class HanakoDatabaseModel < ActiveRecord::Base self.abstract_class = true establish_connection :hanako_database end class TaroUser < TaroDatabaseModel end class HanakoUser < HanakoDatabaseModel end |
TaroUser と HanakoUser はそれぞれ、どのデータベースを参照するでしょうか。
正解は、TaroUser は taro_database、HanakoUser は hanako_database を参照します。
その理由は、データベースの接続情報はサブクラスに引き継がれるからです。
言い換えると、上記コードのように taro_database を参照するモデルは全て TaroDatabaseModel を継承する、hanako_database を参照するモデルは全て HanakoDatabaseModel を継承する、とすれば、establish_connection を全てのモデルクラスで呼び出す必要はありません。
まとめ
まとめです。
- establish_connection でデータベースに接続する。
- オプションは database.yml に記述する内容と同じ。
- database.yml の項目を参照する場合は、項目名を文字列またはシンボルで渡す。
- モデルごとに接続先データベースが決まる場合は、クラス定義の内側で establish_connection を呼び出す。
- 同じモデルでも状況に応じて接続先データベースが異なる場合は、User.establish_connection のように外部から呼び出すと良い。
- データベースの接続情報はサブクラスに引き継がれる(共通の親クラスを作成すると楽)。
Enjoy Rails!