我有一些模特,它是自我指涉的。它包含somethings
,可以是child
或parent
,也可以是两者。
有可能做这样的事吗?
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
答案 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