📫

【Rails】コメント機能非同期通信化

2023/08/11に公開

🍍今回

コメント機能の非同期通信化をおこなう!

🍍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 %>

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.erbdestroy.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