在页面刷新时显示重复评论(在初始 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中描述了这个。

资源