通过自我的孩子拥有自己

时间:2013-10-18 14:24:37

标签: ruby-on-rails activerecord associations ruby-on-rails-4

我有一些模特,它是自我指涉的。它包含somethings,可以是childparent,也可以是两者。 有可能做这样的事吗?

class Class < ActiveRecord::Base
    belongs_to :parent, class_name: 'Class', foreign_key: :parent_id
    has_many :children, class_name: 'Class', foreign_key: :parent_id
    has_many :somethings, foreign_key: :something_id
    has_many :somethings, through: :children, foreign_key: :something_id
end

我想做的是调用类似parent.somethings的内容并获取它们的完整列表。 现在,我得到的是stack level too deep错误。 没有最后一行(has_many :somethings, through: :children, foreign_key: :something_id),我只能获得child.somethings,而且效果很好。

所以基本上我想得到somethings的列表,其中包含每个somethings child parent的{​​{1}}。

提前致谢!

P.S。我完全需要ActiveRecord::Associations::CollectionProxy,所以创建收集somethings的方法,我认为是不可能的。

P.P.S。对不起,如果我的英语不太好:p

3 个答案:

答案 0 :(得分:2)

实际上,在Active Record Query Interface进行了大约一个小时的研究后,我自己找到了答案 这很简单,所以我做到了:

class SomeClass < ActiveRecord::Base
    belongs_to :parent, class_name: 'Class', foreign_key: :parent_id
    has_many :children, class_name: 'Class', foreign_key: :parent_id
    has_many :somethings

    def all_somethings(order)
      Something.joins(some_class: :parent).where("some_class_id = :id OR parents_some_classes.id = :id", {id: self.id}).uniq.order(order)
    end
end

我得到了我想要的东西!

答案 1 :(得分:0)

我会尝试将其拆分为一个实例方法,让所有孩子的somethings像这样:

class Class < ActiveRecord::Base
  belongs_to :parent, class_name: 'Class', foreign_key: :parent_id
  has_many :children, class_name: 'Class', foreign_key: :parent_id
  has_many :somethings, foreign_key: :something_id

  def all_somethings
    return unless self.children.empty?
    (self.children + self.children.map(&:all_somethings)).uniq
  end
end

答案 2 :(得分:0)

我正在撰写Jonathan的更新答案,以避免多次调用:all_somethings并进行查询以获取所有结果。我希望这也会给你带来结果。

class Class < ActiveRecord::Base
  belongs_to :parent, class_name: 'Class', foreign_key: :parent_id
  has_many :children, class_name: 'Class', foreign_key: :parent_id
  has_many :somethings, foreign_key: :something_id
  has_many :childrens_somethings, through: :children, foreign_key: :something_id,
            class_name: "Something"

  def all_somethings
    return unless self.children.empty?
    (self.children + self.children_somethings).uniq
  end
end