RoR:通过另一个has_many获取has_many关联

时间:2014-07-20 18:22:08

标签: ruby-on-rails

我关注官方文档:http://guides.rubyonrails.org/association_basics.html,第4.3.3.4节

我有以下模特:

class Nomination < ActiveRecord::Base
  belongs_to :festival
  has_many :festival_histories, -> { includes :awards }
  attr_accessible :name
end

class FestivalHistory < ActiveRecord::Base
  has_many :awards
  belongs_to :nomination
  belongs_to :festival
end

class Award < ActiveRecord::Base
  belongs_to :festival_history
  belongs_to :case, inverse_of: :awards
  has_attached_file :image
  attr_accessible :name, :festival_history_id, :image
end

在文档中看起来非常相似(对我而言)。

但是当我在控制台中这样做时:

 n = Nomination.first
 n.festival_histories.awards

我得到了

NoMethodError: undefined method `awards' for #<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_FestivalHistory:0x000001019cd400>

我重新加载了控制台,所以问题肯定不存在......

3 个答案:

答案 0 :(得分:1)

class Nomination < ActiveRecord::Base
  belongs_to :festival
  has_many :festival_histories, -> { includes :awards }
  has_many :awards, through: :festival_histories
  attr_accessible :name
end

然后你可以打电话

Nomination.first.awards

答案 1 :(得分:1)

文档没有问题:)

正如 JTG 所说,你不能在所有的festival_histories上获得奖励,只能在具体的历史上获得奖励。

区别在于:

使用 include选项:

n = Nomination.first
Nomination Load (0.4ms) SELECT "nominations".* FROM "nominations" ORDER BY "nominations"."id" ASC LIMIT 1

n.festival_histories
FestivalHistory Load (25.5ms)  SELECT "festival_histories".* FROM "festival_histories" WHERE "festival_histories"."nomination_id" = ?  [["nomination_id", 1]]
Award Load (0.7ms)  SELECT "awards".* FROM "awards" WHERE "awards"."festival_history_id" IN (1)

n.festival_histories.first.awards
NO QUERY!

没有 include选项:

n = Nomination.first
Nomination Load (0.4ms) SELECT "nominations".* FROM "nominations" ORDER BY "nominations"."id" ASC LIMIT 1

n.festival_histories
FestivalHistory Load (25.5ms)  SELECT "festival_histories".* FROM "festival_histories" WHERE "festival_histories"."nomination_id" = ?  [["nomination_id", 1]]

n.festival_histories.first.awards
Award Load (0.7ms)  SELECT "awards".* FROM "awards" WHERE "awards"."festival_history_id" = ?  [["festival_history_id", 1]]

我认为差异显而易见:)

答案 2 :(得分:0)

这是你的控制台出了什么问题,因为festival_histories是一个记录集合,你不能得到集合的awards,只能获得单独的记录。而不是

n = Nomination.first
n.festival_histories.awards

你需要

n = Nomination.first
n.festival_histories.each { |r| puts r.awards}

查看每个festival_history的奖励。

(是的,你是如何include:延迟加载:awards正在运行,这在文档中不是错误;))