非同期通信の実装(コメント機能)

非同期通信の実装

今回はコメント機能に非同期通信を実装していく。

  • 下記関連記事

コメント機能の実装 URL:コメント機能の実装 - takifugu’s blog

いいね機能に非同期通信の実装 URL:非同期通信の実装(いいね機能) - takifugu’s blog

実装の手順

  1. ajax処理をするための記述を追加する(remote :true、local: false)

  2. コメント数の部分テンプレート作成

  3. 部分テンプレートを読み込む箇所にクラス名の記述

  4. コメント機能実行後リダイレクト先を削除(book_commentsコントローラ)

  5. js.erbの作成

前提条件

jQuery導入済み(yarnでインストール)

導入方法参考URL https://nomad.office-aship.info/rails-yarn-jquery/

コメント機能に非同期通信の実装

ajax処理をするための記述を追加する(remote :true、local: false)

非同期通信を行う記述に変更していく。

まずはコメントの投稿機能について記述していく。

app/views/book_comments/_form.html.erb

# local: falseに変更
<%= form_with(model:[book, book_comment], local: false) do |f| %>
  <%= f.text_area :comment, rows:'5', placeholder:"コメントをここに", class:"w-100" %>
  <%= f.submit "送信" %>
<% end %>

form_withの記述をlocal: falseに変更。

次に、コメント削除機能について記述していく。

app/views/book_comments/_index.html.erb

<td>
  <% if book_comment.user == current_user %>
    # remote: trueを追加
    <%= link_to "Destroy", book_book_comment_path(book, book_comment), method: :delete, remote: true, class: "btn btn-sm btn-danger", "data-confirm" => "本当に消しますか?" %>
  <% end %>
</td>

link_toの記述にremote: trueを追加。

コメント数の部分テンプレート作成

views/book_commentsフォルダにコメント数の部分テンプレート_counter.html.erbを作成する。

app/views/book_comments/_counter.html.erb

コメント数:<%= book.book_comments.count %>
部分テンプレートを読み込む箇所にクラス名の記述

部分テンプレートを読み込む箇所にクラス名を記述していく。

app/views/books/show.html.erb

:
    # classを追加、コメント表示を部分テンプレートを読み込む記述に変更
    <td class="book-comments-counter">
      <%= render 'book_comments/counter', book: @book %>
    </td>
:
    # classを追加
    <div class="book-comments-index">
      <%= render 'book_comments/index', book: @book %>
    </div>
    <%= render 'book_comments/form', book: @book, book_comment: @book_comment %>
:

また、コメント投稿の部分テンプレートのコメント記述エリアにクラス名を記述する。

app/views/book_comments/_form.html.erb

<%= form_with(model:[book, book_comment], local: false) do |f| %>
  # comment-textareaのclassを追加
  <%= f.text_area :comment, rows:'5', placeholder:"コメントをここに", class:"w-100 comment-textarea" %>
  <%= f.submit "送信" %>
<% end %>
リダイレクト先を削除(book_commentsコントローラ)

app/controllers/book_comments.rb

class BookCommentsController < ApplicationController
  def create
    book = Book.find(params[:book_id])
    #インスタンス変数に変更
    @comment = current_user.book_comments.new(book_comment_params)
    @comment.book_id = book.id
    @comment.save
    #redirect記述削除
    #redirect_to request.referer
  end

  def destroy
    #記述変更
    @comment = BookComment.find(params[:id])
    @comment.destroy
    #redirect記述削除
    #redirect_to request.referer
  end
:

リダイレクト先を削除することで、createアクションでは、create.js.erbを探しにいき、

destroyアクションでは、destroy.js.erbを探しにいく。

ローカル変数commentをインスタンス変数に変更する。

js.erbの作成

views/book_commentsフォルダにcreate.js.erbとdestroy.js.erbを作成する。

app/views/book_comments/create.js.erb

$('.comment-textarea').val("")
$('.book-comments-counter').html("<%= j(render 'book_comments/counter', book: @comment.book) %>")
$('.book-comments-index').html("<%= j(render 'book_comments/index', book: @comment.book) %>")

app/views/book_comments/destroy.js.erb

$('.book-comments-counter').html("<%= j(render 'book_comments/counter', book: @comment.book) %>")
$('.book-comments-index').html("<%= j(render 'book_comments/index', book: @comment.book) %>")

jQueryの基本構文

$("セレクタ").メソッド("パラメータ[引数]");

セレクタには変更する箇所のクラス名の指定をする(「id」やクラス、グループなどの記述が可能。)

今回使用するメソッドは.html()と.val()の2つである。

.html()で指定のHTMLに変更するというメソッド。

.val()でHTMLタグ内に記述されているvalue属性を取得したり変更することができるメソッド。

$('.book-comments-counter').html("<%= j(render 'book_comments/counter', book: @comment.book) %>")の記述で、

.book-comments_counterクラス内のhtmlをrender 'book_comments/counter', book: @comment.bookに書き換える。

$('.book-comments-index').html("<%= j(render 'book_comments/index', book: @comment.book) %>")も同様に、記述を書き換える。

$('.comment-textarea').val("")の記述で、コメント欄を空欄にしている。destroy時は必要ないため、createのみ記述。

以上でコメント機能に非同期通信の実装が完了。