コメント投稿、削除機能の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