##対象者
いいね機能を実装している方で同期処理はできており、非同期処理の挙動とならない方
リロードしないと「いいねしている状態といいねしていない状態の切り替え」ができない方
Rails6におけるjQuery導入方法(①参照)やデバッグがうまくできていない(②参照)方
##環境
Rails6 環境
Turbolinks導入済み
記事の目的
いいね機能において同期処理は実現できたが、非同期にする上で詰まった部分を記しておきたいと思います。
いいね機能の記事は良質なものがあるので(ただRails5の環境が多いかも?)そちらを基本にして頂き、本記事では初学者が詰まった時に参考になる部分があればいいなという思いで記事にしました。
また、初学者の為、間違いがあれば、ご指摘頂けると幸いです。
##①Rails5とRails6におけるJQuery導入方法の違いを理解していなかった(環境設定ミス)
現在出ている記事ではRails5環境のものが多いのですが、Rails6環境での設定方法と異なることに注意しましょう。
###Rails5の場合
Rails5系までは、「アセットパイプライン」を使用して、JavaScriptを管理します。
gem 'jquery-rails'
//= require jquery
//= require rails-ujs
以上のようにjquery-railsを導入することでRailsアプリケーション開発にJQueryを用いることができます。
その後、app/assets/javasctipts/application.jsなどのマニフェストファイル上でJQueryをrequireします。
私は、Rails6を導入していたのにも関わらず、このRails5の方法で記述してしまいました。
この部分に限らず、Railsのバージョンに気をつけて記事を参照して下さい。
###Rails6の場合
Rails6以降では「Webpacker」という機能で管理します。
私の場合、application.jsの配置場所はapp/javascript/packs/application.jsとなっていました。
require("@rails/ujs").start()
require("turbolinks").start()
require('jquery')
導入に関しては以下の記事を参考にしました。
https://techtechmedia.com/jquery-webpacker-rails/
加えてenvironment.jsの編集、jQuery導入の確認方法についてもこちらの記事で触れています。
jQuery導入の確認方法については、以下で少し触れます。
###jQuery導入の確認方法
application.jsに以下のコードを入れ、
require("@rails/ujs").start()
require("turbolinks").start()
require('jquery')
document.addEventListener("turbolinks:load", () => {
console.log($.fn.jquery)
})
remote:trueの記述によるJavascriptのリクエストによって呼び出されるjs.erbファイルにconsole.log($.fn.jquery)を追加。
console.log($.fn.jquery)
$("#like_<%= @review.id%>").html("<%= j(render partial: "reviews/likes", locals: { review: @review, book: @book, likes: @likes })%>");
そうすると、デベロッパーツールのconsoleの部分でJQueryのバージョンが表示されます。
JavaScriptで非同期処理を実装する際に確認する場所となるので覚えておきましょう。
consoleの部分に「3.5.1」のようにバージョンが表示されていれば、導入ができてるということになります。
##②変数定義のエラーに気づかなかった(rails sによるエラーのログを確認しなかった)
$("#like_<%= @review.id%>").html("<%= j(render partial: "reviews/likes", locals: { review: @review, book: @book, likes: @likes })%>");
エラー出ていないと勘違いしていたのですが、rails sで出力されるログを確認しておりませんでした。
いいねボタンを押すとrails sのログが出力され、一番最後にidが未定義ですとエラーが出ていました。
rails sのログは、以下の通りです。
Started POST "/books/2/reviews/3/likes" for ::1 at 2020-10-24 09:41:59 +0900
Processing by LikesController#create as JS
・
.
(省略)
・
.
ActionView::Template::Error (undefined method `id' for nil:NilClass):
1: $("#like_<%= @review.id %>").html("<%= j(render partial: "reviews/likes", locals: { review: @review, book: @book, likes: @likes })%>");
一番下にエラーがでています。
私の場合は、コントローラ内の@reviewの定義方法の誤りで値が入っていないのが理由で、@reviewを含むcreate.js.erbが動作せず、非同期の挙動になりませんでした。
このエラーに対する適切なデバック(変数の正しい定義)を行ったら、リロードしないと「いいねしている状態といいねしていない状態の切り替え」ができなかった問題が解決され、非同期処理の挙動を実現することができました。
同じような環境・部分で詰まっている方の参考になれば幸いです。