开发者

Rails Associations Through Multiple Levels

开发者 https://www.devze.com 2023-02-14 05:41 出处:网络
I am relatively new to Rails and am working on a project that involves multiple, \"nested\" levels of data. I am having issues making the proper associations so I can get all the child elements of a m

I am relatively new to Rails and am working on a project that involves multiple, "nested" levels of data. I am having issues making the proper associations so I can get all the child elements of a model 3 levels higher. Here is an example of the models:

class Country < ActiveRecord::Base
  has_many :states
end

class State < ActiveRecord::Base
  belongs_to :country
  has_many :cities
end

class City < ActiveRecord::Base
  belongs_to :state
  has_many :people
end

class Person < ActiveRecord::Base
  belongs_to :city
end

I have implemented a relationship in the Country model, has_many :cities, :through => :states and have tried to call Country.first.cities.all, which works. However, I am having issues accessing all 开发者_开发问答the people in a given country when I try Country.first.cities.all.people.all in the People controller.

What is the best way to deal with this sort of association situation? Should I add a foreign key to each of the children tables, such as country_id, so that I can get all the People in a Country? Any suggestions would be appreciated.


The reason is that Country.first.cities.all is an array, and each of it's elements has the method people, instead of the entire collection of cities. You'll notice that this works:

Country.first.cities.first.people.all

Because the first city of the first country has the people method. To get a list of all people in a country, you could do the following in a single query:

People.joins(:city => {:state => :country})
  .where(:country => {:id => Country.first.id}).all


It's beacouse

Country.first.cities.all

is a collection of cities and it doesn't have people method.

You should go with

Country.first.cities.all.each do |city|
    city.people
end
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号