1
votes

What I'd like to do is join one model to another using two intermediary models in between..Here's the abstraction:

Country has_many Companies
Company has_many Buildings, Company belongs_to Country
Building has_many Rooms, Building belongs_to Company
Room belongs_to Building

I want to be able to do Country.first.rooms, so I thought the Country model would be as simple as:

class Country < ActiveRecord::Base
  has_many :companies
  has_many :buildings, :through=>:companies
  has_many :rooms, :through=>:buildings
end

However, this tries to generate SQL like: SELECT * FROM rooms INNER JOIN buildings ON rooms.building_id = building.id WHERE ((building.country_id = 1))

Obviously, building.country_id does not exist. How do I get around this?

3
What's your Rails (specifically ActiveRecord) version?steel

3 Answers

1
votes

The built in association methods won't help you here. You need to build the query explicitly using joins:

class Country - ActiveRecord::Base

    has_many :companies
    has_many :buildings, :through=>:companies

    def rooms
      Room.all :joins => { :building => { :company => :country } }, :conditions => { "countries.id" => id }
    end

end

This will require the belongs_to associations to be set up on the Building and Company models

0
votes

This is possible after Rails 3.1. The below code works for me. It's important to specify the has_many at each level.

class Country
  has_many :companies
  has_many :buildings, through: :companies
  has_many :rooms, through: buildings
end

class Company
  has_many :buildings
end

class Building
  has_many :rooms
end

class Room
end