我有一个通过很棒的嵌套集表示的组织层次结构Node 模型上的太好了,效果很好,更新很昂贵,但发现非常有效。
每个 Node 模型在其他模型上都有_many,我们称它们为 Foo 和 Bar。
class Node < ActiveRecord::Base
acts_as_nested_set
has_many :foos
has_many :bars
end
class Foo < ActiveRecord::Base
belongs_to :node
end
通常,我想找到给定子树的所有 foos 或 bar,从当前节点向下看。天真地,我可以这样做:
@foos = @node.self_and_descendants.collect(&:foos).compact
我什至可以使用 ActiveRecord .includes(:foos) 来避免 N+1 查询。我真正想要的只是要求,@node.all_foos
所以我实现了这样的东西:
class Node < ActiveRecord::Base
def all_foos
Foo.where(node_id: self_and_descendants.pluck(:id))
end
# More efficient?
def all_foos_alternately
Foo.where(node_id: self_and_descendants.includes(:foos).pluck(:id))
end
end
但是,假设我想“收集”的不仅仅是 foos 和 bar,假设我有半打或一打这样的模型。现在我用一堆 all_* 方法在我的 Node 类或一些库中乱扔垃圾。
我是否应该在接受节点作为参数的 foos 和 bar 上定义类方法并返回该子树的所有 foos/bars?但是 foos 和 bar 需要了解/了解 node.self_and_descendants。
或者 Foo 类方法可以接受节点集合,不需要知道嵌套的 set 方法,但是我失去了简单的接口 vianode.all_foos
等。
我在这里缺少什么模式或方法?我已经node.all_*
尝试通过 method_missing 实现一个包罗万象的方法,但不喜欢性能下降。我在这里尝试执行的是,其核心是数据库查找,因此它应该是高效和优雅的。