🪴
Rails 非同期でコメント機能実装
コメント機能を非同期通信を用いて実装
いいね機能に引き続き、コメント機能を実装!
実装する機能
- ビュー
- コメント一覧を部分テンプレートとすること
- サーバーからのレスポンスでコメント一覧のテンプレートを返すこと
- コメントの投稿後、コメントフォームの値に前回の投稿が残らないようにしましょう
- form_withを使うこと
完成
1. jQueryの記述
Gemfile
gem 'jquery-rails'
bundle install
2. 非同期したい部分を部分テンプレート化
コメント一覧表示部分
削除ボタンのlink_to部分に、非同期対応にするために
remote:true, data: {"turbolinks" => false}
を追記
views/post_comments/_show.html.erb
<div class="d-inline-flex flex-column">
<% book.post_comments.each do |post_comment| %>
<div class="d-flex">
<div class="mb-3">
<%= image_tag post_comment.user.get_profile_image(50, 50) %><br>
<%= link_to post_comment.user.name, user_path(post_comment.user) %>
</div>
<div class="ml-3">
<%= post_comment.comment %>
<% if post_comment.user == current_user %>
<%= link_to "Destroy" , book_post_comment_path(book, post_comment), class: "btn btn-sm btn-danger" ,method: :delete , remote:true, data: {"turbolinks" => false} %>
<% end %>
</div>
</div>
<% end %>
</div>
コメント投稿フォーム
form_withにlocal: false
を追記
_form.html.erb
<div class="mt-3">
<%= form_with model: [ book, post_comment ], local: false do |f| %>
<%= render 'partial/error_messages', object: f.object %>
<%= f.text_area :comment, placeholder: "コメントをここに", class: "w-100" %><br>
<%= f.submit "送信" %>
<% end %>
</div>
3. idをつける
renderを記述するときidをつける。
コメント件数を表示する部分にもidをつける。
views/books/show.html.erb
<td>コメント件数:<span id="comment_count"><%= @book.post_comments.count %></span></td>
<div id="post-comments">
<%= render "post_comments/show" , { book: @book , post_comment: @post_comment } %><br>
</div>
<div id="comment-form">
<%= render "post_comments/form" , { book: @book , post_comment: @post_comment } %>
</div>
books/_index.html.erb
<td>コメント件数:<span id="comment_count"><%= book.post_comments.count %></span></td>
4. コントローラーのredirect先を削除
redirect先を消すことによって、そのアクション名のjsファイルを探しにいくようになる。
controllers/post_comments_controller.rb
class PostCommentsController < ApplicationController
def create
@book = Book.find(params[:book_id])
@user = @book.user
@post_comment = current_user.post_comments.new(post_comment_params)
@post_comment.book_id = @book.id
@post_comment.save
#redirect_to book_path(@book)
end
def destroy
@post_comment = PostComment.find(params[:id]).destroy
@post_comment.destroy
@book = Book.find(params[:book_id])
#redirect_to request.referer
end
private
def post_comment_params
params.require(:post_comment).permit(:comment)
end
end
5. js.erb作成
アクション名と一緒のjs.erbを作成
destroy.js.erb
$('#post-comments').html("<%= j(render "post_comments/show", book: @book) %>");
$('#comment_count').html("<%= @book.post_comments.count %>")
create.js.erb
$('#post-comments').html("<%= j(render "post_comments/show", book: @book) %>");
$('#comment_count').html("<%= @book.post_comments.count %>")
$("textarea").val('');
ここではjQueryの記述方法になっている。
jQueryの基本型
$(“セレクタ”).メソッド(“パラメータ[引数]”);
$(“”)
の部分にidを入れることでそこの部分を呼び出し、
.html("");
の部分で、htmlに対して何をするかを()内に記述してく。
今回はアクション後表示したい部分を記載している。
コメント数のカウント部分に関しては、両方に関することなので両方のファイルに
$('#comment_count').html("<%= @book.book_comments.count %>")
で記述。
createの部分は、コメント作成後は削除機能も含めてコメント一覧部分へ表示させたいので、
$('#book-comments').html("<%= j(render "book_comments/commentslist", book: @book) %>");
追加後は、boxをカラにしたいので、$("textarea").val('');
としている。
🌱参考にさせていただいた記事
復習がてらまた作り直してみました🏋🏻
Discussion