在页面刷新时显示重复评论(在初始 AJAX 追加之后)[Rails]
Showing duplicate comment on page refresh (after initial AJAX append) [Rails]
似乎无法弄清楚这一点...在我的 rails 应用程序中,我有 Post 和评论资源。创建新评论时,我想使用 AJAX 重新加载评论列表。该部分似乎可以正常工作——但是,当随后重新加载整个页面时,列表还会显示评论的副本,如 screenshot 所示。关于可能导致此问题的原因有什么想法吗?
(注意:删除其中一条评论也会删除重复的评论)
views/users/show.html.haml
= form_for([post, post.comments.build], remote: true) do |f|
= f.text_field :content, placeholder: 'Press ENTER to submit...', class: "comment_content", id: "comment_content_#{post.id}"
- if post.comments
.comments{ id: "comments_#{post.id}" }
- post.comments.each do |comment|
= render post.comments, post: post
views/comments/_comment.html.haml
- unless comment.content == nil
.comment{ id: "comment_#{comment.id}" }
.user-name
= link_to comment.user.identities.first.nickname, comment.user
.comment-content
= comment.content
- if comment.user == current_user
= link_to post_comment_path(post, comment), data: { confirm: "Are you sure?" }, method: :delete, remote: true do
%i.fa.fa-close
controllers/comments_controller.rb
class CommentsController < ApplicationController
before_action :set_post
def create
@comment = @post.comments.build(comment_params)
@comment.user_id = current_user.id
if @comment.save
respond_to do |format|
format.html { redirect_to :back }
format.js
end
else
render root_path
end
end
...
views/comments/create.js.erb
$('#comments_<%= @post.id %>').append("<%=j render @post.comments, post: @post, comment: @comment %>");
$('#comment_content_<%= @post.id %>').val('')
更新
根据@uzaif 的建议,我将“.append”替换为“.html”。仅当我也将代码移出 _comment 部分时,这才解决了问题。这不是一个理想的解决方案...我仍然想知道 if/how 我可以解决问题并保留我的个人评论。
问题
您看到了重复的评论,因为您无意中将您的评论呈现了两次。
- post.comments.each do |comment|
= render post.comments, post: post
调用 render
并传递一个集合作为第一个参数,指示 Rails 呈现 所有 评论。在内部 Rails 将遍历每个评论并使用对象的部分呈现它。
通过将这个 render
调用(其中已经有一个循环)包装在 另一个 循环中,您实际上是在渲染每个评论两次。
解决方案
删除外部 post.comments.each
循环,让 render
方法完成它。
= render post.comments
Rails 知道将名为 comment
的局部变量传递给每个部分,并且您应该能够通过调用 comment.post
来引用原始 post(假设评论 belongs_to :post
).
小心你如何称呼render
有几种不同的方法可以使用集合中的数据呈现部分。 确保您知道自己使用的是哪一款,不要混用它们。
我在another Whosebug post中描述了这个。
资源
似乎无法弄清楚这一点...在我的 rails 应用程序中,我有 Post 和评论资源。创建新评论时,我想使用 AJAX 重新加载评论列表。该部分似乎可以正常工作——但是,当随后重新加载整个页面时,列表还会显示评论的副本,如 screenshot 所示。关于可能导致此问题的原因有什么想法吗?
(注意:删除其中一条评论也会删除重复的评论)
views/users/show.html.haml
= form_for([post, post.comments.build], remote: true) do |f|
= f.text_field :content, placeholder: 'Press ENTER to submit...', class: "comment_content", id: "comment_content_#{post.id}"
- if post.comments
.comments{ id: "comments_#{post.id}" }
- post.comments.each do |comment|
= render post.comments, post: post
views/comments/_comment.html.haml
- unless comment.content == nil
.comment{ id: "comment_#{comment.id}" }
.user-name
= link_to comment.user.identities.first.nickname, comment.user
.comment-content
= comment.content
- if comment.user == current_user
= link_to post_comment_path(post, comment), data: { confirm: "Are you sure?" }, method: :delete, remote: true do
%i.fa.fa-close
controllers/comments_controller.rb
class CommentsController < ApplicationController
before_action :set_post
def create
@comment = @post.comments.build(comment_params)
@comment.user_id = current_user.id
if @comment.save
respond_to do |format|
format.html { redirect_to :back }
format.js
end
else
render root_path
end
end
...
views/comments/create.js.erb
$('#comments_<%= @post.id %>').append("<%=j render @post.comments, post: @post, comment: @comment %>");
$('#comment_content_<%= @post.id %>').val('')
更新
根据@uzaif 的建议,我将“.append”替换为“.html”。仅当我也将代码移出 _comment 部分时,这才解决了问题。这不是一个理想的解决方案...我仍然想知道 if/how 我可以解决问题并保留我的个人评论。
问题
您看到了重复的评论,因为您无意中将您的评论呈现了两次。
- post.comments.each do |comment|
= render post.comments, post: post
调用 render
并传递一个集合作为第一个参数,指示 Rails 呈现 所有 评论。在内部 Rails 将遍历每个评论并使用对象的部分呈现它。
通过将这个 render
调用(其中已经有一个循环)包装在 另一个 循环中,您实际上是在渲染每个评论两次。
解决方案
删除外部 post.comments.each
循环,让 render
方法完成它。
= render post.comments
Rails 知道将名为 comment
的局部变量传递给每个部分,并且您应该能够通过调用 comment.post
来引用原始 post(假设评论 belongs_to :post
).
小心你如何称呼render
有几种不同的方法可以使用集合中的数据呈现部分。 确保您知道自己使用的是哪一款,不要混用它们。
我在another Whosebug post中描述了这个。