如何在 rails 中正确呈现嵌套评论?
How to properly render nested comments in rails?
我试图让嵌套评论在 rails 5 应用程序中正常工作,运行 遇到了很多困难。
我正在构建一个问答网站,我有一个 Acomment 模型,其中有属于答案的评论,还有属于其他评论的评论:
class Acomment < ApplicationRecord
belongs_to :answer
belongs_to :user
belongs_to :parent, class_name: "Acomment", optional: true
has_many :replies,
class_name: "Acomment", foreign_key: :parent_id, dependent: :destroy
end
我想显示所有评论,然后显示所有对评论的回复,以及对回复的回复等。但是我不知道如何使嵌套正常工作。
在我看来,在每个循环中,我正在渲染 _comment.html.erb
部分:
<% answer.acomments.each do |comment| %>
<%= render :partial=>"comment", :object=>comment %>
<% end %>
然后,在我的 _comment.html.erb
局部中,我正在显示评论、回复 link,然后呈现评论回复的局部:
<div>
<%= comment.body %>
<%= link_to "Reply", new_acomment_path(:parent_id => comment, :answer_id => comment.answer) if comment.parent_id.blank? %>
<%= render partial: "reply", collection: comment.replies %>
</div>
这是 _reply.html.erb
部分:
<%= reply.body %>
<%= link_to "Reply", new_acomment_path(:parent_id => reply, :answer_id => reply.answer) %>
我 运行 遇到两个问题:
1) 当我渲染第一个部分时,它不仅渲染了评论,还同时渲染了回复(因为它们也是评论)。
2) 当我渲染第二部分(回复)时,它们没有嵌套在它们应该嵌套的评论中。一切都乱了。
编辑:
我希望看到这个:
Comment 1
Comment on Comment 1
Comment on Comment on Comment 1
Comment 2
但我看到的是:
Comment 1
Comment on Comment 1
Comment 2
Comment on Comment 1
Comment on Comment on Comment 1
Comment on Comment on Comment 1
如有任何帮助,我们将不胜感激。
对于问题的第一部分,您可能需要一些范围来帮助您区分 "parent comments"(即不是回复的评论)和 "child comments"(回复)。
类似于:
class Acomment < ApplicationRecord
belongs_to :answer
belongs_to :user
belongs_to :parent, class_name: "Acomment", optional: true
has_many :replies, class_name: "Acomment", foreign_key: :parent_id, dependent: :destroy
scope :is_parent, where(parent_id: nil)
scope :is_child, where("parent_id IS NOT NULL")
end
您可以使用下面的这些示例在主循环中仅渲染 parents...目的是每个 parent 将渲染其自己的 children.
<% answer.acomments.is_parent.each do |comment| %>
<%= render :partial=>"comment", :object=>comment %>
<% end %>
关于你的第二个问题 - 我需要更多信息 - 我会在上面的评论中提问。
之后:
所以...我对发生的事情的猜测是:您只是获得了所有评论(如您所提到的)并且它们显示在外循环中(而不只是 parents在外循环中显示)并且它们是按该顺序排列的,因为那是评论的 database-order。
由于 partials 中的默认命名约定,内部循环中实际上没有显示任何内容。
如果您在部分中使用 collection
- Rails 会将每个项目提供给部分...然后以部分名称命名局部变量。在这种情况下,您正在尝试呈现一个名为 "reply" 的部分,但传递了一组注释...因此该部分将寻找一个名为 "reply".
的变量
我建议您只重复使用您已经使用的相同 "comment" 部分,而不是这样渲染它:
<div>
<%= comment.body %>
<%= link_to "Reply", new_acomment_path(:parent_id => comment, :answer_id => comment.answer) if comment.parent_id.blank? %>
<%= render partial: "comment", collection: comment.replies %>
</div>
它将是递归的(就像 Pablo 的建议一样),因此通过缩进每组 sub-comments.
来呈现评论线程
查看您与 pablo 的对话...parents
可能是范围的错误名称...听起来它可能会干扰同名的 ruby-method遍历 class 层次结构...所以这可能是个坏名字 - 因此我将重命名范围。
正如 Taryn 所写,您首先需要过滤没有 parent_id 的评论,这意味着它们是对答案的第一级评论。
views/answers/show.html.erb
<%= @answer.text %>
<h4>Comments</h4>
<% @answer.acomments.parents.each do |comment| %>
<%= render :partial=>"comment", locals: { comment: comment } %>
<% end %>
那么你需要一个递归的方法:
views/acomments/_comment.html.erb
<div>
<%= comment.body %>
<%= link_to "Reply", new_acomment_path(:parent_id => comment, :answer_id => comment.answer) if comment.parent_id.blank? %>
<% comment.replies.each do |reply|
<%= render :partial => "comment", locals: { comment: reply } %>
<% end %>
</div>
您需要提供一些缩进,以便清楚注释之间的层次结构。
我试图让嵌套评论在 rails 5 应用程序中正常工作,运行 遇到了很多困难。
我正在构建一个问答网站,我有一个 Acomment 模型,其中有属于答案的评论,还有属于其他评论的评论:
class Acomment < ApplicationRecord
belongs_to :answer
belongs_to :user
belongs_to :parent, class_name: "Acomment", optional: true
has_many :replies,
class_name: "Acomment", foreign_key: :parent_id, dependent: :destroy
end
我想显示所有评论,然后显示所有对评论的回复,以及对回复的回复等。但是我不知道如何使嵌套正常工作。
在我看来,在每个循环中,我正在渲染 _comment.html.erb
部分:
<% answer.acomments.each do |comment| %>
<%= render :partial=>"comment", :object=>comment %>
<% end %>
然后,在我的 _comment.html.erb
局部中,我正在显示评论、回复 link,然后呈现评论回复的局部:
<div>
<%= comment.body %>
<%= link_to "Reply", new_acomment_path(:parent_id => comment, :answer_id => comment.answer) if comment.parent_id.blank? %>
<%= render partial: "reply", collection: comment.replies %>
</div>
这是 _reply.html.erb
部分:
<%= reply.body %>
<%= link_to "Reply", new_acomment_path(:parent_id => reply, :answer_id => reply.answer) %>
我 运行 遇到两个问题:
1) 当我渲染第一个部分时,它不仅渲染了评论,还同时渲染了回复(因为它们也是评论)。
2) 当我渲染第二部分(回复)时,它们没有嵌套在它们应该嵌套的评论中。一切都乱了。
编辑: 我希望看到这个:
Comment 1
Comment on Comment 1
Comment on Comment on Comment 1
Comment 2
但我看到的是:
Comment 1
Comment on Comment 1
Comment 2
Comment on Comment 1
Comment on Comment on Comment 1
Comment on Comment on Comment 1
如有任何帮助,我们将不胜感激。
对于问题的第一部分,您可能需要一些范围来帮助您区分 "parent comments"(即不是回复的评论)和 "child comments"(回复)。
类似于:
class Acomment < ApplicationRecord
belongs_to :answer
belongs_to :user
belongs_to :parent, class_name: "Acomment", optional: true
has_many :replies, class_name: "Acomment", foreign_key: :parent_id, dependent: :destroy
scope :is_parent, where(parent_id: nil)
scope :is_child, where("parent_id IS NOT NULL")
end
您可以使用下面的这些示例在主循环中仅渲染 parents...目的是每个 parent 将渲染其自己的 children.
<% answer.acomments.is_parent.each do |comment| %>
<%= render :partial=>"comment", :object=>comment %>
<% end %>
关于你的第二个问题 - 我需要更多信息 - 我会在上面的评论中提问。
之后:
所以...我对发生的事情的猜测是:您只是获得了所有评论(如您所提到的)并且它们显示在外循环中(而不只是 parents在外循环中显示)并且它们是按该顺序排列的,因为那是评论的 database-order。
由于 partials 中的默认命名约定,内部循环中实际上没有显示任何内容。
如果您在部分中使用 collection
- Rails 会将每个项目提供给部分...然后以部分名称命名局部变量。在这种情况下,您正在尝试呈现一个名为 "reply" 的部分,但传递了一组注释...因此该部分将寻找一个名为 "reply".
我建议您只重复使用您已经使用的相同 "comment" 部分,而不是这样渲染它:
<div>
<%= comment.body %>
<%= link_to "Reply", new_acomment_path(:parent_id => comment, :answer_id => comment.answer) if comment.parent_id.blank? %>
<%= render partial: "comment", collection: comment.replies %>
</div>
它将是递归的(就像 Pablo 的建议一样),因此通过缩进每组 sub-comments.
来呈现评论线程查看您与 pablo 的对话...parents
可能是范围的错误名称...听起来它可能会干扰同名的 ruby-method遍历 class 层次结构...所以这可能是个坏名字 - 因此我将重命名范围。
正如 Taryn 所写,您首先需要过滤没有 parent_id 的评论,这意味着它们是对答案的第一级评论。
views/answers/show.html.erb
<%= @answer.text %>
<h4>Comments</h4>
<% @answer.acomments.parents.each do |comment| %>
<%= render :partial=>"comment", locals: { comment: comment } %>
<% end %>
那么你需要一个递归的方法:
views/acomments/_comment.html.erb
<div>
<%= comment.body %>
<%= link_to "Reply", new_acomment_path(:parent_id => comment, :answer_id => comment.answer) if comment.parent_id.blank? %>
<% comment.replies.each do |reply|
<%= render :partial => "comment", locals: { comment: reply } %>
<% end %>
</div>
您需要提供一些缩进,以便清楚注释之间的层次结构。