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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:55:57  来源:igfitidea点击:

ActiveRecord, has_many :through, and Polymorphic Associations

ruby-on-railsactiverecordpolymorphic-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.

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