ActiveRecord,has_many:through和Polymorphic Associations

伙计们,

要确保我正确理解这一点。 请忽略inheritance的情况(SentientBeing),而不是集中在has_many中的多态模型上:通过关系。 这就是说,考虑以下…

class Widget < ActiveRecord::Base has_many :widget_groupings has_many :people, :through => :widget_groupings, :source => :person, :conditions => "widget_groupings.grouper_type = 'Person'" has_many :aliens, :through => :widget_groupings, :source => :alien, :conditions => "video_groupings.grouper_type = 'Alien'" end class Person < ActiveRecord::Base has_many :widget_groupings, :as => grouper has_many :widgets, :through => :widget_groupings end class Alien < ActiveRecord::Base has_many :widget_groupings, :as => grouper has_many :widgets, :through => :widget_groupings end class WidgetGrouping < ActiveRecord::Base belongs_to :widget belongs_to :grouper, :polymorphic => true end 

在一个完美的世界里,我想给一个小工具和一个人做一些事情:

 widget.people << my_person 

但是,当我这样做的时候,我注意到了'grouper'的'type'在widget_groupings中总是为null。 但是,如果我像下面这样:

 widget.widget_groupings << WidgetGrouping.new({:widget => self, :person => my_person}) 

然后,所有的工作,正如我通常所料。 我不认为我曾经见过这种非多态关联发生,只是想知道这是否是特定于这个用例,或者如果我潜在地盯着一个错误。

谢谢你的帮助!

Rails 3.1.1有一个已知的问题 ,打破了这个function。 如果遇到这个问题,请先尝试升级,在3.1.2中已经修复

你太亲近了 问题是你滥用:source选项。 :source应该指向多态的belongs_to关系。 然后,您只需指定source_type即可定义关系。

这个Widget模型的修复应该可以让你做你正在寻找的东西。

 class Widget < ActiveRecord::Base has_many :widget_groupings has_many :people, :through => :widget_groupings, :source => :grouper, :source_type => 'Person' has_many :aliens, :through => :widget_groupings, :source => :grouper, :source_type => 'Alien' end 

如上所述,由于源代码上的错误,这不适用于rails 3.1.1,但在Rails 3.1.2中已经修复

有很多:通过和多态不协同工作。 如果您尝试直接访问它们,它应该会引发错误。 如果我没有弄错,你必须手写widget.people和push例程。

我不认为这是一个错误,这只是一个尚未实现的东西。 我想我们可以看到它的特点,因为每个人都有一个他们可以使用它的情况。