我正在使用嵌套集来表示嵌套注释(1个讨论中有很多注释,注释可以回复),我想(如果可能的话)急于加载注释的答案。
此刻我加载所有根节点并迭代它们,如果它们有后代我会渲染它们。但是,如果有很多根节点都有答案,则会触发很多数据库请求。
评论包含以下列:
rgt, lft, parent_id
我试图建立这样的关系:
class Comment < ActiveRecord::Base
has_many :answers, -> (node) { where("lft > ? AND rgt < ?", node.lft, node.rgt) }, class_name: "Comment", foreign_key: :parent_id
end
在Comment实例上调用时,它会获取注释的答案。但是,如果我尝试eager_load它(Discussion.comments.includes(:answers)
),它会因为node
为零而爆炸。
是否有可能急于加载这样的东西?
答案 0 :(得分:1)
我想,我找到了解决方案。 如果我看对了,那么您的数据模型如下所示:
Discussion
----------
...
Comment
----------
discussion_id:int
parent_id:int
lft:int
rgt:int
然后AR模型类将是:
class Discussion < ActiveRecord::Base
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :discussion
end
急切加载讨论(id == 1)及其所有评论和答案树使用:
d = Discussion.includes(:comments).find(1)
这给出了内存中给定讨论的所有注释的集合(d.comments
)。
现在我们可以操作此集合来获取任何特定注释的答案,而无需额外的数据库查询。只需将其添加到Discussion
类:
def comment_roots
self.comments.select {|c| c.parent_id.nil? }
end
这到Comment
类:
def answers
self.discussion.comments.select {|c| c.parent_id = self.id }
end
def answers_tree
self.discussion.comments.select {|c| self.lft < c.lft && c.rgt < self.rgt }
end
示例:
d.comment_roots.first.answers