ActiveRecord、has_many :through 和多态关联
伙计们,
想确保我正确理解这一点。并且请忽略这里继承的情况(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 中始终为空。但是,如果我执行以下操作:
widget.widget_groupings << WidgetGrouping.new({:widget => self, :person => my_person})
那么一切都会按我通常的预期进行。我认为我从未见过这种情况发生在非多态关联中,只是想知道这是否是该用例特有的,或者我是否可能正在关注一个错误。
感谢您的帮助!
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...
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.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.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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Rails 3.1.1 存在一个已知问题,该问题会破坏此功能。如果您遇到此问题,请先尝试升级,该问题已在 3.1.2 中修复,
您已经很接近了。问题是您滥用了 :source 选项。 :source 应该指向多态belongs_to 关系。然后您需要做的就是为您要定义的关系指定 :source_type 。
对 Widget 模型的此修复应该允许您准确地执行您想要的操作。
There is a known issue with 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
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.
This fix to the Widget model should allow you do exactly what you're looking for.
如上所述,由于 :source 上的错误,这不适用于 Rails 3.1.1,但在 Rails 3.1.2 中已修复
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
例如:
位置
有许多火车
、直升机
、卡车
、轮船
。火车
、直升机
、卡车
、轮船
有许多位置
。不同的位置可以有类似的传输(存储在可移动的多态列中)。
使用:
For example:
locations
have manytrains
,copters
,trucks
,ships
. Andtrains
,copters
,trucks
,ships
have manylocations
.Different
locations
can have similar transports(store inmoveable
polymorphic columns).Using:
有很多 :through 和多态不能一起工作。如果您尝试直接访问它们,它应该会抛出错误。
如果我没记错的话,你必须手写 widget.people 和推送例程。
我不认为这是一个错误,这只是尚未实现的东西。我想我们会在该功能中看到它,因为每个人都有可以使用它的情况。
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.
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.