コメント投稿、削除機能のajax化
手順
①commentsコントローラーの修正
②コメント作成、削除機能をajax化
③コメント作成、削除時の動的レンダリング処理を追加
1. commentsコントローラーの修正
コメント作成時の redirect_back を削除し、コメント削除処理を追加します。
app/controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
@comment = current_user.comments.build(comment_params)
@comment.save
end
def destroy
@comment = current_user.comments.find(params[:id])
@comment.destroy!
end
コメント削除のルートを追加します。
config/routes.rb
Rails.application.routes.draw do
resources :boards do
resources :comments, only: %i[create destroy], shallow: true
collection do
get :bookmarks
end
end
end
コメント作成、削除機能をajax化
form_with の local: true を削除して非同期処理にします。
form_withはデフォルトでremote: trueなので明示的に記載しなくても良い。
app/views/comments/_form.html.erb
<div class="row mb-3">
<div class="col-lg-8 offset-lg-2">
<%= form_with model: comment, url: [board, comment], id: 'new_comment' do |f| %>
<%= f.label :body %>
<%= f.text_area :body, class: 'form-control mb-3', id: 'js-new-comment-body', row: 4, placeholder: Comment.human_attribute_name(:body) %>
<%= f.submit t('defaults.post'), class: 'btn btn-primary' %>
<% end %>
</div>
</div>
コメントの削除ボタン link_to に remote: true を追加します。
app/views/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),
class: 'js-delete-comment-button',
method: :delete,
data: { confirm: t('defaults.message.delete_confirm') },
remote: true do %>
<%= icon 'fa', 'trash' %>
<% end %>
</li>
</ul>
</td>
<% end %>
</tr>
コメント作成、削除時の動的レンダリング処理を追加
コメントの追加に成功した場合、追加したコメントをコメント一覧に追加する処理をjavascriptで実装します。
また、コメントの追加に失敗した場合は、エラーメッセージを表示するようにします。
app/views/comments/create.js.erb
# 既に表示されているエラーメッセージがあった場合は削除する
$("#error_messages").remove()
# コメント作成処理の結果によって処理を分岐させる
<% if @comment.errors.present? %>
# エラーがある、処理失敗時にはエラーメッセージのパーシャルを表示させる
$("#new_comment").prepend("<%= j(render('shared/error_messages', object: @comment)) %>")
<% else %>
# エラーがない、処理成功時には作成されたコメント内容をHTML要素として追加する
$("#js-table-comment").prepend("<%= j(render('comments/comment', comment: @comment)) %>")
# コメント入力フォームのテキストは表示する必要がないので、空文字に置き換えて内容をクリアする
$("#js-new-comment-body").val('')
<% end %>
「prepend()」メソッドは、指定の要素内に文字列やHTML要素を追加することができるメソッドになります。
一般的な記述方法としては、【 対象要素.prepned( 追加したい要素 ) 】になります。
このようにjQueryのメソッドを使うために各所にidを指定しています。
コメントの追加と同様に、コメントの削除した時にコメントリストから対象のコメントを取り除きます。
app/views/comments/destroy.js.erb
$("tr#comment-<%= @comment.id %>").remove()
# こっちでもok
$('#<%= "comment-#{@comment.id}"%>').remove()
参考元