Search code examples
ruby-on-railsactiverecordhas-many-throughruby-on-rails-4.2

Encountering relationship issues with ActiveRecord has_many through on two different databases


I'm trying to setup a has_many :through relationship over two different databases and encountering an issue.

My models are as follow:

company:

# this model lives in database main_db
class Company < ActiveRecord::Base
  has_many :company_custom_plans
  has_many :custom_plans, through: :company_custom_plans
end

custom_plan

# this model lives in database other_app_db
class CustomPlan < ActiveRecord::Base
  has_many :company_custom_plans
  has_many :companies, through: :company_custom_plans
end

joint model:

# this model lives in other_app_db
class CompanyCustomPlan < ActiveRecord::Base
  belongs_to :custom_plan
  belongs_to :company
end

### Schema ###
#  create_table "company_custom_plans", force: :cascade do |t|
#    t.integer "company_id",     limit: 4, null: false
#    t.integer "custom_plan_id", limit: 4, null: false
#  end

So it works quite great on the Company model but when trying to use this relation on the CustomPlan I'm getting an error because the has_many :through looks for the company_custom_plans in main_db instead of other_app_db

example:

ccp = CompanyCustomPlan.create!(company: company, custom_plan: custom_plan)
company.company_custom_plans == [ccp] # true
company.custom_plans == [custom_plan] # true
custom_plan.company_custom_plans == [ccp] # true

custom_plan.companies # error
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'main_db.company_custom_plans' doesn't exist: SHOW FULL FIELDS FROM `company_custom_plans`

I tried to play with the different options of has_many :through (like setting source: 'company') but cannot figure out how to make this work.

Thanks,


Solution

  • I ended up figuring out how to force the has_many :through to use the right database following this stackoverflow answer.

    class CompanyCustomPlan < ActiveRecord::Base
    
      self.table_name = "#{ActiveRecord::Base.connection.current_database}.company_custom_plans"
    
      belongs_to :custom_plan
      belongs_to :company
    end