コメント投稿、削除機能のajax化

コメント作成、削除処理のajax

・コメントの投稿フォームを処理をajax化するので、form_withをremote: trueにして、サーバーのログでjs形式で送信されているか確認 ちなみに、form_withはデフォルトでremote: trueなので明示的に記載しなくても良い

#comments/_form.html.erb
<div class="row mb-3">
  <div class="col-lg-8 offset-lg-2">
    <%= form_with model: [board, comment], remote: true,id: 'new_comment' do |form| %>
      <%= form.label :body %>
      <%= form.text_area :body, class: "form-control mb-3", row: "4", placeholder: Comment.human_attribute_name(:body) %>
      <%= form.submit t('defaults.post'), class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

コメントの削除のリンクのlink_toにremote: trueを追加、リンク先をcomment_path(comment)と指定

#comments/_comment.html.erb
<tr id="comment-<%= comment.id %>">

                                      中略

  <% if current_user.own?(comment) %>
    <td class="action">
      <ul class="list-inline justify-content-center" style="float: right;">
 
                                      中略
    
        <li class="list-inline-item">
          <%= link_to comment_path(comment), method: :delete, remote: true, class: 'js-delete-comment-button', data: {confirm: 'よろしいですか'} do %>
            <%= icon 'fas', 'trash' %>
          <% end %>
        </li>
      </ul>
    </td>
  <% end %>
</tr>

comments_controller.rbの修正

#comments_controller.rb
class CommentsController < ApplicationController
  before_action :set_comment, only: %i[update destroy]
  def create
    @comment = current_user.comments.create(comment_params)
  end

  def destroy
    @comment.destroy!
  end

  private

  def set_comment
    @comment = current_user.comments.find(params[:id])
  end

redirect_backの処理を削除して、set_commentで削除するコメントのインスタンスを取得して置くことでアクションを簡潔にしている

コメント作成、削除時の動的レンダリング処理を追加

#comments/create.js.erb
$("#error-messages").remove();
<% if @comment.errors.present? %>
  $("#new_comment").prepend("<%= j(render('shared/error_messages', object: @comment)) %>");
<% else %>
  $("#js-table-comment").prepend("<%= j(render('comments/comment', comment: @comment)) %>");
  $("#js-new-comment-body").val('');
<% end %>

#comments/destroy.js.erb
$("#comment-<%= @comment.id %>").remove();

create.js.erbではもしコメントインスタンスがバリデーションに引っかかり、エラーオブジェクトを持っている場合、prependメソッドで指定した要素の子要素の先頭にshared/error_messagesとパーシャルファイルを追加している。エラーオブジェクトがなければ、同じくprependメソッドを使って、コメントのパーシャル部分だけをレンダリングするようにしている。また投稿成功時、コメントフォームvalue属性をvalで空文字を指定してリセットしている。
destroy.js.erbではremoveメソッドで指定した要素を全て削除している

参考文献

Rails で JavaScript を使用する - Railsガイド

【Rails】Ajax(非同期通信)でコメント投稿、削除 - Qiita

jQuery 要素を追加する(before/after/prepend/append) | ITSakura

val(val) - jQuery 日本語リファレンス