ActiveRecord, has_many :through, 与 STI 的多态关联 [英] ActiveRecord, has_many :through, Polymorphic Associations with STI

查看:52
本文介绍了ActiveRecord, has_many :through, 与 STI 的多态关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ActiveRecord、has_many :through 和多态关联中,OP 的示例请求忽略 AlienPerson (SentientBeing) 的可能超类.这就是我的问题所在.

class Widget <ActiveRecord::Basehas_many :widget_groupingshas_many :people, :through =>:widget_groupings, :source =>:person, :source_type =>'人'has_many :外星人, :through =>:widget_groupings, :source =>:alien, :source_type =>《外星人》结尾SentientBeingActiveRecord::Basehas_many :widget_groupings, :as =>石斑鱼has_many :widgets, :through =>:widget_groupings结尾类人<有情众生结尾类外星人<有情众生结尾

在这个修改过的例子中,AlienPersongrouper_type 值现在都被 Rails 存储为 SentientBeing(Rails 为这个 grouper_type 值寻找基类).

在这种情况下,修改 Widget 中的 has_many 以按类型过滤的正确方法是什么?我希望能够做 Widget.find(n).peopleWidget.find(n).aliens,但目前这两种方法 (.people.aliens) 返回空集 [] 因为 grouper_type 总是 SentientBeing.

解决方案

您是否尝试过最简单的方法 - 将 :conditions 添加到 has_many :throughs 中?>

换句话说,像这样(在 widget.rb 中):

has_many :people, :through =>:widget_groupings, :conditions =>{:类型=>'人' }, :source =>:grouper, :source_type =>'SentientBeing'has_many :外星人, :through =>:widget_groupings, :conditions =>{:类型=>'外星人' }, :source =>:grouper, :source_type =>'SentientBeing'

JamesDS 是正确的,需要连接 - 但这里没有写出来,因为 has_many :through 关联已经在做了.

In ActiveRecord, has_many :through, and Polymorphic Associations, the OP's example requests ignoring the possible superclass of Alien and Person (SentientBeing). This is where my question lies.

class Widget < ActiveRecord::Base
  has_many :widget_groupings

  has_many :people, :through => :widget_groupings, :source => :person, :source_type => 'Person'
  has_many :aliens, :through => :widget_groupings, :source => :alien, :source_type => 'Alien'
end

SentientBeing < ActiveRecord::Base
  has_many :widget_groupings, :as => grouper
  has_many :widgets, :through => :widget_groupings
end


class Person < SentientBeing
end

class Alien < SentientBeing
end

In this modified example the grouper_type value for Alien and Person are now both stored by Rails as SentientBeing (Rails seeks out the base class for this grouper_type value).

What is the proper way to modify the has_many's in Widget to filter by type in such a case? I want to be able to do Widget.find(n).people and Widget.find(n).aliens, but currently both of these methods (.people and .aliens) return empty set [] because grouper_type is always SentientBeing.

解决方案

Have you tried the simplest thing - adding :conditions to the has_many :throughs?

In other words, something like this (in widget.rb):

has_many :people, :through => :widget_groupings, :conditions => { :type => 'Person' }, :source => :grouper, :source_type => 'SentientBeing'
has_many :aliens, :through => :widget_groupings, :conditions => { :type => 'Alien' }, :source => :grouper, :source_type => 'SentientBeing'

JamesDS is correct that a join is needed - but it's not written out here, since the has_many :through association is already doing it.

这篇关于ActiveRecord, has_many :through, 与 STI 的多态关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆