14

My environment: Ruby 1.9.2p290, Rails 3.0.9 and RubyGem 1.8.8

unfortunately I have an issue when come across multiple database.

The situation is this: I have two model connect with two different database and also establishing association between each other. database connection specifying in each model, look likes

class Visit < ActiveRecord::Base
  self.establish_connection "lab"
  belongs_to :patient
end

class Patient < ActiveRecord::Base
  self.establish_connection "main"
  has_many :visits
end

I got an error when meet following scenario

@visits = Visit.joins(:patient)

Errors: Mysql2::Error: Table 'lab.patients' doesn't exist: SELECT visits.* FROM visits INNER JOIN patients ON patients.id IS NULL

Here 'patients' table is in 'main' database and 'visits' table in 'lab' database I doubt when executing the code, that Rails is considering 'patients' table is part of 'lab' database [which holds 'visits' table].

5 Answers5

10

Well, I don't know if this is the most elegant solution, but I did get this to work by defining self.table_name_prefix to explicitly return the database name.

class Visit < ActiveRecord::Base
  def self.table_name_prefix
    renv = ENV['RAILS_ENV'] || ENV['RACK_ENV']
    (renv.empty? ? "lab." : "lab_#{renv}.")
  end

  self.establish_connection "lab"
  belongs_to :patient
end

class Patient < ActiveRecord::Base
  def self.table_name_prefix
    renv = ENV['RAILS_ENV'] || ENV['RACK_ENV']
    (renv.empty? ? "main." : "main_#{renv}.")
  end

  self.establish_connection "main"
  has_many :visits
end

I'm still working through all the details when it comes to specifying the join conditions, but I hope this helps.

Daniel Cukier
  • 11,502
  • 15
  • 68
  • 123
srosenhamer
  • 116
  • 2
7

Might be cleaner to do something like this:

  def self.table_name_prefix
    "#{Rails.configuration.database_configuration["#{Rails.env}"]['database']}."
  end

That will pull the appropriate database name from your database.yml file

3

Or even

def self.table_name_prefix
   self.connection.current_database+'.'
end
Emil
  • 7,220
  • 17
  • 76
  • 135
2

Is your 2nd database on another machine? You can always do as suggested in this other question:

MySQL -- Joins Between Databases On Different Servers Using Python?

Community
  • 1
  • 1
Mark Bolusmjak
  • 23,606
  • 10
  • 74
  • 129
  • No. both database are in same machine. Rails looks appropriate database when calling visits and Patient separately. 'visits= Visit.first.patient' and vise versa works fine. Problem only when joining both models. – Manivannan Jeganathan Nov 02 '11 at 05:33
0

I'd use the self.table_name_prefix as proposed by others, but you can define it a little more cleanly like this:

self.table_name_prefix "#{Rails.configuration.database_configuration["#{Rails.env}"]['database']}."

alternatively you could also use this:

self.table_name_prefix "#{connection.current_database}."

You have to keep in mind that the latter will execute a query SELECT DATABASE() as db the first time that class is loaded.

jeroenj
  • 31
  • 1
  • 2