【rails】いいね機能 非同期編
やっとできたので書いていきます。
↓前回まで
【rails】いいね機能実装 (追記あり) - 技術系ブログ
参考: 第14章 ユーザーをフォローする - Railsチュートリアル
[https://qiita.com/tambo/items/45211df065e0c037d032:title]
【Rails初心者】Ajaxの実装方法を理解する(非同期通信) - Qiita
導入手順
①jqueryを使えるようにします。
②remote: true 追加
③.js.erbファイル作成
④コントローラー側編集です。
そもそも非同期通信とは、
参考:非同期処理:コールバック/Promise/Async Function · JavaScript Primer #jsprimer
初心者目線でAjaxの説明 - Qiita
その前に同期通信は 同期処理ではコードを順番に処理していき、ひとつの処理が終わるまで次の処理は行いません。
同期処理では実行している処理はひとつだけとなるため、とても直感的な動作となります。
つまり、 同期処理ではひとつの処理が終わるまで、次の処理へ進むことができない。
非同期通信は、ひとつの非同期処理が終わるのを待たずに次の処理を評価します。
つまり、非同期処理では同時に実行している処理が複数あります。
一部分のみの更新とう言う感じですかね。
Ajaxとは
Asynchronous JavaScript + XML (AJAX) はそれ自体がある種の技術というわけではありませんが、
Jesse James Garrett によって 2005 年に作られた言葉で、既存の技術同士を組み合わせた新しいアプローチを意味します。
Ajax - Wikipedia
準備
jqueryを使えるようにします。
gem 'jquery-rails'
#app/asssets/javascripts/application.js -# バージョンがRails5.1以降の場合 //= require jquery //= require rails-ujs -# Rails5.1より前の場合 //= require jquery //= require jquery-ujs
view側
#app/views/likes/_like.html.slim -if current_user.likes.find_by(post_id: @post.id) #liked = link_to post_like_path(@post, current_user.likes.find_by(post_id: @post.id)), method: :delete, remote: true do p いいね済 - else #likable = link_to post_likes_path(@post,current_user.likes.build),method: :post, remote: true do p いいね
(@post, current_user.likes.find_by(post_id: @post.id))
,(@post,current_user.likes.build)
のように書いてアクション側にid
を送ります。非同期導入前の段階では書かなくてもエラーが出ませんでしたが、
非同期通信をする際には必要なようです。
またremote: true
とそれぞれにidを追加しています
idを追加するとこで、jqueryのセレクタとして特定することができます。
remote: trueとは
参考:Rails で JavaScript を使用する - Railsガイド
フォームの送信がブラウザによる通常の送信メカニズムではなくAjaxによって送信されるようになります。
追加するだけでAjaxが使えるようになると考えてください。
そして、リクエストがhtml形式からjs形式になります。
つまり.js
ファイルを探すようになります。
詳しく説明すると、link_to post_like_path(@post)
ではhtml形式なら
controllerは「app/views/controller名/アクション名.リクエストの形式.erb」というファイルを探しに行きます。
しかし、今回のpostリクエストでいうと、html形式だとapp/views/likes/create.html.slim
を探しますが,
js形式だとapp/views/likes/create.js.erb
を読み込みます。
.js.erbファイルを作成
.js.erbファイルの作成にはファイル名を注意してください。
link_to先のアクション名に合わせてください。
app/views/controller名/アクション名.js.erb
で作成します。
今回は、create
とdestroy
2つ作ります。
touch app/views/likes/create.js.erb
touch app/views/likes/destroy.js.erb
#app/views/likes/create.js.erb $("#likable").html("<%= escape_javascript(render('likes/like')) %>");
#app/views/likes/destroy.js.erb $("#liked").html("<%= escape_javascript(render('likes/like')) %>");
escape_javascriptメソッドは、JavaScriptファイル内にHTMLを挿入するときに実行結果をエスケープするために必要です。
コントローラー側
下記をcreate,destroyアクションにそれぞれ追加します。
respond_to do |format| format.html { redirect_to @post } format.js end
respond_toメソッド
とは、
上の (ブロック内の) コードのうち、いずれかの1行が実行されます。
#app/controllers/likes_controller.rb class LikesController < ApplicationController before_action :set_post, only: [:create, :destroy] def create @like = current_user.likes.create(like_params) respond_to do |format| format.html { redirect_to @post } format.js end end def destroy @like = Like.find_by(like_params, user_id: current_user.id) @like.destroy respond_to do |format| format.html { redirect_to @post } format.js end end private def set_post @post = Post.find(params[:post_id]) end def like_params params.permit(:post_id) end end
おしまい。