将Rails多态用于嵌套注释

时间:2010-11-29 22:34:41

标签: ruby-on-rails comments polymorphism nested

我需要在Rails 3应用程序中构建一个嵌套的注释系统,允许对许多模型(文章,帖子等)进行评论,并且正在讨论按照this post的方式编写我自己的解决方案。有acts_as_commentable_with_threadingawesome_nested_set等宝石可供使用,但他们觉得我的需求很臃肿。

  1. 我需要能够为多个模型添加评论
  2. 我需要能够为评论添加评论,无限深入
  3. 我需要能够有效地检索帖子,文章等的所有后代
  4. 我需要能够在适当的嵌套中有效地呈现评论
  5. 我的问题是,我是否应该自行解决我可能面临的潜在问题。我想避免走一条路只是为了走向死胡同。我最初的担忧涉及有效地查询儿童。比如说,获取一篇文章后代评论列表(孩子和孩子的孩子)。

    有人对此有所了解吗?感谢。

3 个答案:

答案 0 :(得分:6)

您可以执行两种嵌套:树和嵌套集。

acts_as_tree只存储parent_id,因此编写新条目的速度非常快,但您必须递归遍历ID号链以获取所有子项的列表。当你需要做大量的阅读时,这不是一个好的选择。

awesome_nested_set记录了三位信息:parent_idlftrgt。计算左右值,以便它们包含该条目的所有子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_idawesome_nested_set即可完成剩下的工作。我不认为滚动你自己的解决方案会比这更优雅。

更新:看起来awesome_nested_set在某段时间内尚未更新。请查看ancestry。基本上是一样的。

答案 1 :(得分:1)

树结构,是的,是一个好主意 - 但是查询执行本身是最令人担忧的,我不认为大多数树实现作为一个宝石考虑到这一点,而嵌套集是正常的 - 我估计如果发生了一些非常糟糕的事情,它在写操作方面会过于复杂。

我会查看Recursive CTEs - 虽然不是数据库不可知的,但它为您提供了一个很好的数据结构,无需额外的属性来跟踪。

答案 2 :(得分:0)

我以前通过在评论表中添加以下字段来做这样的事情:

attached_to_controller(string)

attached_to_id(int)

然后在显示时我会对注释索引进行AJAX调用并根据这两个字段进行过滤。

当然,在创建评论时,您需要为这些字段传递适当的值。