Ruby-on-rails ActiveRecord、has_many :through 和多态关联
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1683265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ActiveRecord, has_many :through, and Polymorphic Associations
提问by Cory
Folks,
各位,
Want to make sure I understand this correctly. And please disregard the case for inheritance here (SentientBeing), trying to instead focus on polymorphic models in has_many :through relationships. That said, consider the following...
想确保我正确理解这一点。并且请忽略此处的继承情况(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
In a perfect world, I'd like to, given a Widget and a Person, do something like:
在一个完美的世界中,给定一个 Widget 和一个 Person,我想执行以下操作:
widget.people << my_person
However, when I do this, I've noticed the 'type' of the 'grouper' is always null in widget_groupings. However, if I to something like the following:
但是,当我这样做时,我注意到 widget_groupings 中“grouper”的“type”始终为空。但是,如果我像下面这样:
widget.widget_groupings << WidgetGrouping.new({:widget => self, :person => my_person})
Then all works as I would have normally expected. I don't think I've ever seen this occur with non polymorphic associations and just wanted to know if this was something specific to this use case or if I'm potentially staring at a bug.
然后一切都像我通常预期的那样工作。我认为我从未见过这种与非多态关联发生的情况,只是想知道这是否是特定于这个用例的东西,或者我是否可能正在盯着一个错误。
Thanks for any help!
谢谢你的帮助!
回答by EmFi
There is a known issuewith Rails 3.1.1 that breaks this functionality. If you are having this problem first try upgrading, it's been fixed in 3.1.2
Rails 3.1.1有一个已知问题会破坏此功能。如果您遇到此问题,请先尝试升级,它已在 3.1.2 中修复
You're so close. The problem is you're misusing the :source option. :source should points to the polymorphic belongs_to relationship. Then all you need to do is specify :source_type for the relationship you're trying to define.
你离得那么近。问题是您滥用了 :source 选项。:source 应该指向多态的belongs_to 关系。然后您需要做的就是为您尝试定义的关系指定 :source_type 。
This fix to the Widget model should allow you do exactly what you're looking for.
对 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
回答by scottkf
As mentioned above, this doesn't work with rails 3.1.1 due to a bug on :source, but it's fixed in Rails 3.1.2
如上所述,由于 :source 上的错误,这不适用于 rails 3.1.1,但它已在 Rails 3.1.2 中修复
回答by cgr
has many :through and polymorphic don't work together. If you try to access them directly, it should throw an error. If i am not mistaken, you have to hand write widget.people and the push routine.
有很多 :through 和 polymorphic 不能一起工作。如果您尝试直接访问它们,它应该会引发错误。如果我没记错的话,你必须手写widget.people 和push 程序。
I don't think it is a bug, it is just something which hasn't been implemented yet. I would imagine we see it in the feature, because everyone has a case in which they could use it.
我不认为这是一个错误,它只是尚未实现的东西。我想我们会在功能中看到它,因为每个人都有一个可以使用它的案例。

