📫
【Rails】コメント機能非同期通信化
🍍今回
コメント機能の非同期通信化をおこなう!
🍍Gemインストール
Gemfileに記述する
Gemfile
gem 'jquery-rails'
ターミナルでbundle install
を実行
bundle install
🍍部分テンプレート化
非同期通信化するためには、行いたい部分を部分テンプレートにする必要がある。
🍍Ajaxの処理を適用
ページを更新することなくページの内容だけを入れ替えられる処理。
form_with 部分 (コメントフォーム)
app/views/post_comments/_form.html.erb
<%= form_with model: [post, post_comment],local: false do |f| %>
<%= f.text_area :comment, rows:'4', placeholder: "コメントをここに", class: "w-100" %>
<%= f.submit "送信" %>
<% end %>
link_to 部分 (削除ボタン)
app/views/post_comments/_index.html.erb
<table>
<!--コメント一覧-->
<tbody>
<% post.post_comments.each do |post_comment| %>
<tr>
<td>
<%= link_to user_path(post_comment.user) do %>
<%= image_tag post_comment.user.get_image(50,50) %><br>
<%= post_comment.user.name %>
<% end %>
</td>
<td><%= post_comment.comment %></td>
<td>
<% if post_comment.user == current_user %>
<!--コメント削除ボタン-->
<%= link_to post_post_comment_path(post, post_comment), method: :delete, class: "btn", remote:true, data: {"turbolinks" => false} do %>
<i class="fa-solid fa-trash-can"></i>
<% end %>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
🍍js.erbファイルの作成
Ajaxの処理を適用したことによってHTTPリクエストではなくJavascriptリクエストが送られるため、JavaScript用のファイルを作成する必要がある。
今回はコメントを行った時のcreateとコメントを消去した時のdestroyを非同期通信化したいためファイル名をcreate.js.erb
とdestroy.js.erb
にしている。
🍍ビューファイルの記述
作成した部分テンプレートをviewページ内に記述する。
この時下記画像のようにidで囲む。
views/posts/show.html.erb
<div id="post_comments">
<%= render 'post_comments/index', post: @post, post_comments: @post_comments %><!--コメント一覧-->
</div>
<div id="comment_form">
<%= render 'post_comments/form', post: @post, post_comment: @post_comment %><!--コメント入力フォーム-->
</div>
💎コメント入力フォームを非同期通信化することでそこで入力した内容が保存されてその内容がコメント一覧に表示されるのは分かるんだけど。
入力フォームのとこcreate.js.erbに記述してないのに何でできるの?
💎💎保存ボタン押した時点でcreateアクションが発動して保存された後に一覧がajaxで表示できるようになったからか!
それだったら、<div id="comment_form">
で囲む必要なくない?
views/post_comments/create.js.erb
$('#post_comments').html("<%= j(render 'post_comments/index', post: @post, post_comments: @post_comments) %>")
$("textarea").val('');
views/post_comments/destroy.js.erb
$('#post_comments').html("<%= j(render 'post_comments/index', post: @post, post_comments: @post_comments) %>");
🍍コントロール
redirect先の消去
controllers/post_comments_controller.rb
def create
@post = Post.find(params[:post_id])
comment = PostComment.new(post_comment_params)
comment.user_id = current_user.id
comment.post_id = @post.id
comment.save!
# redirect_to request.referer #非同期のためコメントアウト
end
def destroy
@post_comment = PostComment.find(params[:id])
@post_comment.destroy!
#redirect_to request.referer 非同期のためコメントアウ
end
Discussion