1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2022-10-19

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

参考元

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?