2008年6月3日火曜日

Multiple Database Connection for Model in Rails(My solution)

In my project, I must talk with multiple database for Model(ex. Student). Unfortunately, Models in Rails can't connect with multiple database by default. After diving in to web, I found nice solution to solve this problem: Magic Multi-Connections plugin. But as written in top page in the project, Models with Magic Multi-Connections has problem with association(one-to-many, many-to-many). I was newbie for ruby, and couldn't understand source code of Magic Multi-Connections for all. So, I gave up using, fixing it and wrote some code for this problem. Here was my idea.

0. Model to use multiple connection

class Students
end

1. Define connection hosts in yaml.

config/students.yml

students:
 conn1: 192.168.1.101
 conn2: 192.168.1.102
 conn3: 192.168.1.103
 conn4: 192.168.1.104
 conn5: 192.168.1.105


2. Load yaml in environment.rb

$students_conn_hosts = YAML.load_file(File.join(RAILS_ROOT, "config/students.yml"))


3. Define Model classes by using "eval".

class StudentAlias

 @@students_conns = []

 1.upto(5) do |i|
  @@students_conns << eval("""
   class StudentModel#{i} <>
    establish_connection( :adapter => 'mysql',
     :host => '#{$students_conn_hosts["students"]["conn" + i.to_s]}',
     :database => 'hoge',
     :encoding => 'utf8',
     :username => 'db_user_name',
     :password => '',
     :timeout => '5000',
     :socket => 'your_socket_name
    )
    set_table_name 'students'
   end
   StudentModel#{i}
  """)
 end

 # select one connection by rand, for example
 def StudentAlias.get_connection
  @@student_conns[rand(@@student_conns.size)]
 end

end


4. Call class method in StudentAlias for Student Model to connect one of databases

StudentAlias.get_connection # => StudentAlias::StudentX(... attribute definitions of student table ...)


Not so bad?

0 コメント: