如何让这个Many_to_Many协会工作

时间:2011-12-10 16:00:17

标签: ruby-on-rails ruby-on-rails-3 associations

我认为这是一个相当简单的很多很多协会,我试图努力工作。我可以从双方进入联接表,但我无法通过联接表到达另一方。我有三种型号:赛马,初学者和种族。模型如下:

class Jockey < ActiveRecord::Base
has_many :starters
has_many :races, :through => :starters
end

class Starter < ActiveRecord::Base
belongs_to :race
belongs_to :jockey
end

class Race < ActiveRecord::Base
has_many :starters
has_many :jockeys, :through => :starters
end

当我这样做时:

Jockey.find(1).starters  # everything works great

当我这样做时:

Race.find(1).starters # everything works great 

但如果我试试这个

Race.find(1).starters.jockeys或Jockeys.find(1).starters.races

我收到错误:

    `Jockey Load (0.0ms)  SELECT "jockeys".* FROM "jockeys" WHERE "jockeys"."id" = 1 LIMIT 1
    NoMethodError:   Starter Load (0.0ms)  SELECT "starters".* FROM "starters" WHERE
 `"starters"."jockey_id" = 1undefined method `races' for


    #<ActiveRecord::Relation:0x4de89831>

我一直试图让这个工作几个小时,但无法弄清楚我做错了什么。任何指导将不胜感激。

2 个答案:

答案 0 :(得分:1)

请注意,startrs不是Starter对象,它是一个关系/集合,您需要先获取其中的对象。 例如

Race.find(1).starters.first.jockey

答案 1 :(得分:1)

Jockeys.find(1)后面是这个sql:

SELECT "jockeys".* FROM "jockeys" WHERE "jockeys"."id" = 1 LIMIT 1

即现在你有一个具体的Jockey对象

但是当你执行Jockeys.find(1).starters.races时,你实际上正在调用ActiveRecord :: Relation实例上的races方法(如错误消息所示),而不是你应该在具体的Starter实例上调用。如果你考虑一下,starters.races真的没有意义 - 你在调用种族方法的对象是什么?

所以你应该这样称呼它:

Jockeys.find(1).starters.first.races

.first为您提供一个具体的Starter对象,您可以在其上调用races方法

但是既然你宣布Jockey has_many:比赛(通过首发加入表),那么获得特定赛马的所有比赛的最简单方法当然是:

Jockeys.find(1).races