2016-11-17 1 views
0

Не может показаться, что это видно ... В моем приложении rails у меня есть ресурсы Post и Comment. Когда создается новый комментарий, я хочу перезагрузить список комментариев с помощью AJAX. Эта часть, похоже, работает надлежащим образом, однако, когда полная страница впоследствии перезагружается, список также показывает дубликат комментария, как показано в этом screenshot. Любые мысли о том, что может быть причиной этого?Показывать дублированный комментарий к обновлению страницы (после первоначального добавления AJAX) [Rails]

(примечание: удаление один из комментариев также удаляет дубликаты)

просмотров/пользователей/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 

просмотров/комментарии/_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 

контроллеры/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 

    ... 

просмотров/комментарии/create.js.erb

$('#comments_<%= @post.id %>').append("<%=j render @post.comments, post: @post, comment: @comment %>"); 
$('#comment_content_<%= @post.id %>').val('') 

Update

По предложению @ uzaif, я заменил «.append» с «.html». Это устранило проблему только в том случае, если я также переместил код из частичной части. На самом деле это не идеальное решение ... Я все равно хотел бы знать, как и как я могу исправить эту проблему и частично оставить свой индивидуальный комментарий.

+0

вместо Append пытаются HTML, который заменит весь 'div' – uzaif

+0

Хорошая мысль, но имели один и тот же результат – Alexdlf

+0

@uzaif так на самом деле, который исправляет проблему, если у меня нет частичного «_comment» (т. е. если я верну этот код обратно в представление «show»). На самом деле это не идеальное решение, но на этот раз он выполнит свою работу :) – Alexdlf

ответ

0

Проблема

Вы видите повторяющиеся комментарии, потому что вы неосторожно рендеринга ваши комментарии дважды.

- 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 (предполагая, что комментарий belongs_to :post).

Будьте осторожны, как вы называете render

Есть несколько различных способов рендеринга партиалы с данными из коллекции. Убедитесь, что вы знаете, какой из них используете, и не смешивайте и не сопоставляйте их.

Описываю это в another StackOverflow post.

Ресурсы
+0

Спасибо! Хотя Rails на самом деле не проходил вдоль переменной 'post', поэтому я прямо указал на это. Помимо этой детали, ваше решение решило мою проблему. – Alexdlf

+0

Ах, да, я ошибочно написал, что он будет передавать 'post' в качестве локальной переменной, но поскольку мы рендерим' post.comments', он будет переходить вместо переменной 'comment'. Вы должны иметь возможность ссылаться на исходное сообщение через комментарий, вызывая 'comment.post'. Я уточнил свой ответ выше с разъяснением. В любом случае, рад, что я мог бы помочь! –

Смежные вопросы