0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Rails6における非同期通信「コメント編」

0
Posted at

はじめに

実装したこと

Rails6におけるコメントの作成と削除の非同期化

動作環境

Ruby 3.1.2
Rails 6.1.7.3

手順

jQueryを導入する

gemではなく、yarnでインストールする。
詳しくはわからないが、Rails6の場合はgem(Rubyのライブラリ)ではなくyarn(Railsmのライブラリ)からインストールする方が良い。

$ yarn add jquery

以上でインストールをする。

そして、以下の追記を行う。

config/webpack/environment.js
const { environment } = require('@rails/webpacker')
// 以下追記
const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)
// ここまで
module.exports = environment

さらに、以下を追記する。

javascript/packs/application.js
//中略

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
// 追記
require('jquery')

//中略

以上で、JQueryは導入できました。

コメントの非同期化を実装

まず、非同期化とは

非同期化とは、送信者のデータ送信タイミングと受信者のデータ受信タイミングを合わせずに通信を行う通信方式を指します。非同期を行えばコメントの作成をフォームから送信した際に、サーバからの結果を待たずに画面にコメントを追加できるようにすることができます。これはユーザ側にとって使いやすいサイトになるメリットがあります。

どの部分を非同期にするかを決める

contents/show.html.erb
<div class="card">
  <div class="card-header">
    <h5 class="card-title">コメント欄</h5>
  </div>
  <div class="card-body">
    <div id="comments_list">
      <%= render "comments_list",content: @content %>
    </div>
    <%= form_with(model: @comment, url: content_comments_path(@content), local: false) do |f| %>
      <div class="form-group">
        <%= f.text_area :comment, class: "form-control comment-textarea" %>
      </div>
      <%= f.submit "コメントする", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

form_withの箇所が、 local: false のところが注意! 通常のlocal: trueの場合は同期通信をしてしまうので、非同期通信の場合はlocal: falseで記載をする。
そして以上の中で、今回は以下のコメントリストの部分を非同期化します。

<div id="comments_list">
  <%= render "comments_list",content: @content %>
</div>

部分テンプレートの中は以下のようにします。

contents/_comments_list.html.erb
<% content.comments.each do |comment| %>
<div class="card mb-3">
  <div class="card-body">
    <p class="card-text"><%= comment.comment %></p>
    <% if comment.user == current_user %>
      <%= link_to '削除', content_comment_path(content, comment), method: :delete, remote: true, class: "btn btn-danger btn-sm" %>
    <% end %>
  </div>
</div>
<% end %>

※非同期化する箇所は必ずパーシャル(部分テンプレート)にしましょう。
※属性はidではなくてもよいが、idの場合値が重複しないようにするので今回は属性をidとしている。

Javascriptファイルを作成する。

views/comments に下記のファイルを作成し以下を記載する。

create.js.erb
$("#comments_list").html("<%= j( render "user/contents/comments_list",content: @content )%>");
destroy.js.erb
$("#comments_list").html("<%= j( render "user/contents/comments_list",content: @content )%>");

処理は同じのため、記載内容は同じになります。
ここでは jQueryの記述方法になっています。

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

ここでは、$(“”)の部分にidを入れることでそこの部分を呼び出し、.html("");の部分で、htmlメソッドを使用しているので、HTMLに対して何をするか、どうするかを()内に記述していく。
今回は先ほど作成した部分テンプレートを呼び出すようにしているので、以上の記載になります。
※<%= j~> ここjの部分は、Javascriptとして呼び出すと命令しているので記載をしないとエラーになります。

最後に

通常は、railsのファイルで、createやdestroyをindexやeditのようにファイルを作らないので違和感がありますが、これは慣れるしかないですね。
以上、随時編集していきます。

参考にさせてもらった記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?