はじめに
実装したこと
Rails6におけるコメントの作成と削除の非同期化
動作環境
Ruby 3.1.2
Rails 6.1.7.3
手順
jQueryを導入する
gemではなく、yarnでインストールする。
詳しくはわからないが、Rails6の場合はgem(Rubyのライブラリ)ではなくyarn(Railsmのライブラリ)からインストールする方が良い。
$ yarn add jquery
以上でインストールをする。
そして、以下の追記を行う。
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
さらに、以下を追記する。
//中略
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
// 追記
require('jquery')
//中略
以上で、JQueryは導入できました。
コメントの非同期化を実装
まず、非同期化とは
非同期化とは、送信者のデータ送信タイミングと受信者のデータ受信タイミングを合わせずに通信を行う通信方式を指します。非同期を行えばコメントの作成をフォームから送信した際に、サーバからの結果を待たずに画面にコメントを追加できるようにすることができます。これはユーザ側にとって使いやすいサイトになるメリットがあります。
どの部分を非同期にするかを決める
<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>
部分テンプレートの中は以下のようにします。
<% 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 に下記のファイルを作成し以下を記載する。
$("#comments_list").html("<%= j( render "user/contents/comments_list",content: @content )%>");
$("#comments_list").html("<%= j( render "user/contents/comments_list",content: @content )%>");
処理は同じのため、記載内容は同じになります。
ここでは jQueryの記述方法になっています。
$(“セレクタ”).メソッド(“パラメータ[引数]”);
ここでは、$(“”)の部分にidを入れることでそこの部分を呼び出し、.html("");の部分で、htmlメソッドを使用しているので、HTMLに対して何をするか、どうするかを()内に記述していく。
今回は先ほど作成した部分テンプレートを呼び出すようにしているので、以上の記載になります。
※<%= j~> ここjの部分は、Javascriptとして呼び出すと命令しているので記載をしないとエラーになります。
最後に
通常は、railsのファイルで、createやdestroyをindexやeditのようにファイルを作らないので違和感がありますが、これは慣れるしかないですね。
以上、随時編集していきます。
参考にさせてもらった記事