いいね機能のAjax化
作業した流れ
① link_toにremote: trueを追加する
remote: true追加後、検証でHTMLにコンパイルされたコードがdeta-remote="true"
になっているか確認した。
② link_toのパスはcreateアクションに送られる仕様になっているので、createアクションにbinding.pry
を追加してリクエストの形式を調べてみる
def create binding.pry # 形式を調べるために追加
③ createアクション、destroyアクションを編集
最初アクションにrespond_toメソッドを追加してしまったが、いいねしたかどうかによって即座に☆マーク、★マークが切り替わるいいね機能において、あえてHTMLリクエストの分岐を残す必要はなかった。
投稿の☆マークをクリックし、そのリクエストに対応するコントローラのアクション処理が実行され、アクションと同名のビューファイルが呼び出される。
という流れなので、redirect_backを消すことでcreate.js.erbファイルが呼び出されるようになる。
※リクエストの形式をJS形式に変えているため、{アクション名}.js.erbファイルが呼ばれる。
④ create.js.erb、destroy.js.erbファイルを作成し、処理を記載する
※ bookmarksコントローラの話なので、create.js.erbとdestroy.js.erbファイルはviewsのbookmarksディレクトリ配下に作成する
_favorite.html.erb
<%= link_to favorites_path(post_id: post.id), id: "js-favorites-button-for-post-#{post.id}", class: "float-right", remote: true, method: :post do%> <%= icon 'far', 'star' %> <% end %>
idがjs-favorite-button-for-postの箇所に変更を加えたいため、セレクタにそのidを用いて、replaceWithメソッドで☆→★になるようパーシャルを設定する。
※ 前回のお試しアプリでは、セレクタの記載がclass名だったため、「. セレクタ名」という形で.(ドット)を用いたが今回はidをセレクタとするので、先頭に「#」をつける。
create.js.erb
$("#js-favorite-button-for-post-<%= @post.id %>").replaceWith("<%= j(render('posts/unfavorite', post: @post)) %>");
これに伴い、favoritesコントローラのpostもインスタンス変数に変更する。
destroyもほぼ同様、置き換えるパーシャルを_favorite.html.erbに変えるだけ。
replaceWithメソッドかhtmlメソッドか
replaceWithメソッドはセレクタで指定した箇所を指定した要素に置き換えるメソッド
htmlメソッドは要素のHTMLを取得したり、指定したHTMLを挿入することができるメソッド
$("#js-favorite-button-for-post-<%= @post.id %>").html("<%= j(render('posts/unfavorite', post: @post)) %>");
のように書くと、入れ子状になってしまう。