時々1つのアプリケーションから複数のデータベースにアクセスする必要に迫られることがあります。
たとえば、他のアプリの作ったデータベースにアクセスしたい場合とか。
でも、ActiveRecord のサンプルプログラムのほとんどは、 ActiveRecord::Base に直接設定をセットしているし、
ActiveRecord::Base を使ってコネクションを作成しているので、複数のデータベースの接続を AR をつかって張ることができないです(やりにくい)。
ではどうするか?
ただ、ActiveRecord のサブクラスを作成するだけです。
ActiveRecord::Base のサブクラスは親クラスの読み込んだ設定や、データベースへの接続へアクセスできるので、
まず ActiveRecord::Base のサブクラスを作成して(ここでは BaseDB)これにデータベースの設定をセットします。
それから、 BaseDB を継承した子クラスを作って、その子クラスにそれぞれデータベースへの接続を張らせます。
たぶん、ActiveRecord::Base に直接設定をセットしたり、ActiveRecord::Base で直接データベースへの接続を張るよりも、
子クラスの方でなんとかした方が良さそうです。とくに将来複数のデータベースとかを扱う状況になるかもしれない場合・・・。
- ActiveRecord::Base
- BaseDB < ActiveRecord::Base (これにデータベースの設定などをセットする)
- MyDB < BaseDB (これを使ってデータベース mydb への接続を張る)
- YourDB < BaseDB (これを使ってデータベース yourdb への接続を張る)
- BaseDB < ActiveRecord::Base (これにデータベースの設定などをセットする)
下のサンプルコードが、異なる2つのデータベースに接続する例です。
想定している環境:
- データベース(1)
- databasename : my_db
- username : myname
- password : mypass
- データベース(2)
- databasename : your_db
- username : yourname
- password : yourpass
ディレクトリ構成:
- bin/ar-multi-connections-test.rb : メインプログラム
- config/database.yml : データベースの設定ファイル
- lib/base_db.rb : *_db のベースクラスでデータベースの設定を保持するクラス
- lib/my_db.rb : データベース(1) の my_db 用
- lib/my_table.rb : データベース(1) のテーブル用
- lib/your_db.rb : データベース(2) の your_db 用
- lib/your_table.rb : データベース(2) のテーブル 用
コード
bin/ar-multi-connections-test.rb
#!/usr/bin/env ruby # -*- coding: utf-8 -*- $LOAD_PATH << File.expand_path(File.join('..', 'lib'), File.dirname(__FILE__)) require 'messa/engine/parser' require 'messa/messa_helper' require 'messa/logger_factory' # path to database configuration file config_file = File.expand_path(File.join('..', 'config', 'database.yml'), File.dirname(__FILE__)) BaseDB.load_database_configurations(config_file) MyDB.establish_connection(:mydb_test) YourDB.establish_connection(:yourdb_test)
config/database.yml
mydb_test: adapter: mysql encoding: utf8 database: mydb username: myname password: mypass socket: /var/run/mysqld/mysqld.sock yourdb_test: adapter: mysql encoding: utf8 database: yourdb username: yourname password: mypass socket: /var/run/mysqld/mysqld.sock
lib/base_db.rb
# -*- coding: utf-8 -*- require 'rubygems' require 'activerecord' require 'erb' require 'yaml' class BaseDB < ActiveRecord::Base # #=== load configurations from YAML file # #_config_ :: path to a YAML configuration file # def self.load_configurations(config) # like ActiveRecord::Base.configurations = ... self.configurations = YAML::load(ERB.new(IO.read(config)).result) end # def end # class
lib/my_db.rb
# -*- coding: utf-8 -*- require 'base_db' class MyDB < BaseDB end # class
lib/my_table.rb
# -*- coding: utf-8 -*- require 'my_db' class MyTable < MyDB set_table_name 'my_table' end # class
lib/your_db.rb
# -*- coding: utf-8 -*- require 'base_db' class YourDB < BaseDB end
lib/your_table.rb
# -*- coding: utf-8 -*- require 'your_db' class YourTable < YourDB set_table_name 'your_table' end # class
これだけです。