2015-04-01 46 views
1

我使用嵌套集来表示嵌套注释(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 

这将提取的答案的评论评论实例调用时。但是,如果我尝试eager_load它(Discussion.comments.includes(:answers)),它会爆炸,因为node是零。

是否有可能加载类似这样的东西?

+0

什么'node'?什么是_“所有根节点”_?为什么你的'has_many:answers'里面有'class_name:'Comment''? – smathy 2015-04-01 16:43:32

+0

我的猜测是他有一个共同的模式来回答和评论。只是一个不同的名字。 :P – argentum47 2015-04-01 16:46:44

+0

评论属于讨论(并不重要)。评论有很多答案(答复),这也是评论。一个根节点是一个评论,它不是回复(回复)到另一个评论(parent_id = nil)。 – Linus 2015-04-01 16:57:20

回答

0

我想,我找到了一个解决方案。 如果我看到它,你的数据模型是这样的:

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