有没有办法通过两个has_many关联访问STI表?

时间:2017-08-07 10:16:43

标签: ruby-on-rails ruby activerecord

当我在has_many关系中使用STI时,我想通过超类的关联访问子对象,但是在持久化之前我无法做到。

这些示例代码与我的情况类似。

class Parent < ActiveRecord::Base
  has_many :children, class_name: 'Child', inverse_of: :parent
  has_many :male_children, class_name: 'Children::Male'
  has_many :female_children, class_name: 'Children::Female'
end

class Child < ActiveRecord::Base
  belongs_to :parent, inverse_of: :children
end

class Children::Male < Child
end

class Children::Female < Child
end

当我将has_many关联设置为子类的关联时,我无法通过超类的关联访问。

parent = Parent.new
parent.male_children << Children::Male.new
parent.female_children << Children::Female.new

parent.children # => []

保存并重新加载父级后,当然我可以将超类的子关联作为ActiveRecord从数据库中获取。

parent.save
parent.reolad
parent.children # => [#<Children::Male ...>, #<Children::Female ...>]

我可以通过实现像这样的实例方法来解决这个问题

class Parent < ActiveRecord::Base
  ...
  def children
    [male_children, female_children].flatten
  end
end

但我更喜欢由于某种原因的关联(可预测性,指定参数等)。 那么有谁知道如何设置关联定义,或者这是不可能的?

1 个答案:

答案 0 :(得分:0)

如果您的男/女孩子没有不同的行为,那么这不应该通过STI完成,而只需使用属性。考虑到孩子通常有两个父母的事实,这种模式也不尽如人意。

当你有性别属性时,你可以这样做:

parent.children.where(sex: 'male')

但由于这不能回答你的问题:

parent.male_children.build(name: 'Carl')

应该有用。