dancow
dancow

Reputation: 3388

How to create a has_many relationship between two models, with several models in between? (Ruby on Rails ActiveRecord)

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?

Upvotes: 1

Views: 977

Answers (3)

steel
steel

Reputation: 12570

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

Upvotes: 0

austinfromboston
austinfromboston

Reputation: 3780

Try using nested has many through

Upvotes: 0

derfred
derfred

Reputation: 19891

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

Upvotes: 1

Related Questions