117

伙计们,

想确保我正确理解这一点。并且请忽略此处的继承情况(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

但是,当我这样做时,我注意到 widget_groupings 中“grouper”的“type”始终为空。但是,如果我执行以下操作:

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

然后一切都按我通常的预期工作。我认为我从未见过非多态关联发生这种情况,只是想知道这是否是此用例特有的东西,或者我是否可能正在盯着一个错误。

谢谢你的帮助!

4

3 回答 3

162

Rails 3.1.1的一个已知问题会破坏此功能。如果您遇到此问题,请先尝试升级,它已在 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
于 2009-11-05T23:53:37.717 回答
3

如上所述,由于 :source 上的错误,这不适用于 rails 3.1.1,但它已在 Rails 3.1.2 中修复

于 2011-12-04T13:02:06.207 回答
-4

有很多 :through 和 polymorphic 不能一起工作。如果您尝试直接访问它们,它应该会引发错误。如果我没记错的话,你必须手写widget.people 和push 例程。

我不认为这是一个错误,它只是尚未实现的东西。我想我们会在功能中看到它,因为每个人都有一个可以使用它的案例。

于 2009-11-05T23:21:51.473 回答