非同期通信の実装(コメント機能)
非同期通信の実装
今回はコメント機能に非同期通信を実装していく。
- 下記関連記事
コメント機能の実装 URL:コメント機能の実装 - takifugu’s blog
いいね機能に非同期通信の実装 URL:非同期通信の実装(いいね機能) - takifugu’s blog
実装の手順
ajax処理をするための記述を追加する(remote :true、local: false)
コメント数の部分テンプレート作成
部分テンプレートを読み込む箇所にクラス名の記述
コメント機能実行後リダイレクト先を削除(book_commentsコントローラ)
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のみ記述。
以上でコメント機能に非同期通信の実装が完了。