对嵌套注释使用 Rails 多态性
Posted
技术标签:
【中文标题】对嵌套注释使用 Rails 多态性【英文标题】:Using Rails polymorphism for nested comments 【发布时间】:2011-05-17 13:33:42 【问题描述】:我需要在 Rails 3 应用程序中构建一个嵌套 cmets 系统,该系统允许在许多模型(文章、帖子等)上使用 cmets,并且我正在讨论按照this post 推出我自己的解决方案。有像 acts_as_commentable_with_threading 和 awesome_nested_set 这样的 gem,但它们对于我的需求来说有点臃肿。
-
我需要能够将 cmets 添加到多个模型中
我需要能够将 cmets 添加到 cmets,无限深
我需要能够有效地检索帖子、文章等的所有后代
我需要能够在适当的嵌套中有效地呈现 cmets
我的问题是,如果我推出自己的解决方案,我可能会遇到哪些潜在问题。我想避免走上一条路才走到死胡同。我最初的担忧与有效地查询儿童有关。例如,获取文章后代 cmets(children 和 children 的 children)的列表。
有人对此有意见吗?谢谢。
【问题讨论】:
如果您必须使用 SQL 手动执行此操作,您知道该怎么做吗?如果是这样,我认为如果您可以使用内建命令(例如 belongs_to 和 has_many),这可能会帮助您形象化。这将反过来向您展示您的陷阱,或者是否有可能。 【参考方案1】:您可以进行两种嵌套:树和嵌套集。
acts_as_tree
只存储parent_id
,因此写入新条目确实很快,但是您必须递归遍历 id 号链才能获得所有孩子的列表。当您需要进行大量读取时,这不是一个好的选择。
awesome_nested_set
记录三位信息:parent_id
、lft
和rgt
。计算左值和右值,以便它们包含该条目的所有子 ID。这对于读取操作来说非常快,但对于写入操作来说比较慢。
在你的情况下,我认为awesome_nested_set
更合适。您可能会认为这似乎有点过头了,但嵌套集合很快就会变得复杂。您需要使用嵌套集合模式来有效地查询子项。
您只需要使用两种方法来渲染整个 cmets 树:遍历 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。做基本相同的事情。
【讨论】:
我同意。为此,我已切换回 awesome_nested_set。但是,这种方法不会针对每条评论(即使是那些没有孩子的评论)访问数据库吗?我看到了应该将整个树拉回根的后代方法,但我每次都得到一个空集。【参考方案2】:是的,树结构是一个好主意 - 但是查询执行本身是最受关注的,我认为大多数树实现作为 gem 没有考虑到这一点,虽然嵌套集没问题 -我认为如果真的发生了非常糟糕的事情,那么它在写操作方面过于复杂了。
我会查看 Recursive CTEs - 虽然不是与数据库无关,但它为您提供了一个很好的数据结构,无需跟踪额外的属性即可使用。
【讨论】:
【参考方案3】:我曾经通过在 cmets 表中添加以下字段来做类似的事情:
attached_to_controller(字符串)
attached_to_id (int)
然后在显示时,我将对 cmets 索引进行 AJAX 调用,并根据这两个字段进行过滤。
当然,在创建 cmets 时,您需要为这些字段传递适当的值。
【讨论】:
以上是关于对嵌套注释使用 Rails 多态性的主要内容,如果未能解决你的问题,请参考以下文章
ruby 中:Rails:嵌套路由,多态关联和控制器(https://medium.com/@loickartono/rails-nested-routes-polymorphic-as