我需要在Rails 3应用程序中构建一个嵌套的注释系统,允许对许多模型(文章,帖子等)进行评论,并且正在讨论按照this post的方式编写我自己的解决方案。有acts_as_commentable_with_threading和awesome_nested_set等宝石可供使用,但他们觉得我的需求很臃肿。
我的问题是,我是否应该自行解决我可能面临的潜在问题。我想避免走一条路只是为了走向死胡同。我最初的担忧涉及有效地查询儿童。比如说,获取一篇文章后代评论列表(孩子和孩子的孩子)。
有人对此有所了解吗?感谢。
答案 0 :(得分:6)
您可以执行两种嵌套:树和嵌套集。
acts_as_tree
只存储parent_id
,因此编写新条目的速度非常快,但您必须递归遍历ID号链以获取所有子项的列表。当你需要做大量的阅读时,这不是一个好的选择。
awesome_nested_set
记录了三位信息:parent_id
,lft
和rgt
。计算左右值,以便它们包含该条目的所有子ID。读取操作速度非常快,但写入速度较慢。
在您的情况下,我认为awesome_nested_set
更合适。您可能认为它看起来有点过分,但嵌套集很快就变得复杂了。您需要使用嵌套集模式来有效地查询子项。
您只需要使用两种方法来呈现整个评论树:迭代Comment.roots
,对于每条评论,渲染comment.children
。
class ModelController < ApplicationController
def show
@model = Model.find_by_id(params[:id])
@comments = @model.comments.roots
end
end
<ul id="comments">
<% @comments.each do |comment| %>
<%= render :partial => 'comment', :object => comment %>
<% end %>
</ul>
<!-- _comment partial -->
<li class="comment">
<!-- comment markup -->
<% if comment.children.present? %>
<ul>
<%= render :partial => 'comment', :collection => comment.children %>
</ul>
<% end %>
</li>
要保存嵌套评论,只需填写parent_id
,awesome_nested_set
即可完成剩下的工作。我不认为滚动你自己的解决方案会比这更优雅。
更新:看起来awesome_nested_set
在某段时间内尚未更新。请查看ancestry。基本上是一样的。
答案 1 :(得分:1)
树结构,是的,是一个好主意 - 但是查询执行本身是最令人担忧的,我不认为大多数树实现作为一个宝石考虑到这一点,而嵌套集是正常的 - 我估计如果发生了一些非常糟糕的事情,它在写操作方面会过于复杂。
我会查看Recursive CTEs - 虽然不是数据库不可知的,但它为您提供了一个很好的数据结构,无需额外的属性来跟踪。
答案 2 :(得分:0)
我以前通过在评论表中添加以下字段来做这样的事情:
attached_to_controller(string)
attached_to_id(int)
然后在显示时我会对注释索引进行AJAX调用并根据这两个字段进行过滤。
当然,在创建评论时,您需要为这些字段传递适当的值。