今回は、Railsでお気に入り登録機能をAjaxを使って非同期処理化していきます。
おおまかな手順
- いいねボタンに
remote: true
を追加する - ビューファイルに目印となる
id
を付与する - create, destroyアクションの
redirect_back ...
を削除する - Ajax用のcreate, destroyファイルを作成する
いいねボタンにremote: true
を追加する
いいねボタンは複数のビューで扱うためパーシャルファイルとして定義し、
・ ユーザーがログインしているか
・ ログインユーザーの場合は、いいねしている楽曲があるか
上記2つの条件をもとに分岐表示をしています。
以下のlink_toタグ
にremote: true
を追加し、Ajaxで処理できるようにする。
app/views/likes/_like_button.html.erb
<% if logged_in? && current_user.liked_by?(music: music) %>
<%= link_to like_path(music), method: :delete, remote: true do %>
<i class="fa-solid fa-heart" style="color: deeppink;"></i>
<% end %>
<% else %>
<%= link_to likes_path(music), method: :post, remote: true do %>
<i class="fa-regular fa-heart"></i>
<% end %>
<% end %>
ビューファイルに目印となるid
を付与する
Ajaxを使用して、処理する場合対象となるHTMLファイルに目印となるid
を指定してあげる必要がある。
今回は<div id="favorite_button_<%= music.id %>">
を指定しました。
app/views/shared/_music_view.html.web
<div class="max-w-screen-2xl py-5 md:px-6 mx-auto">
#省略
<div class="flex items-center">
<div id="favorite_button_<%= music.id %>">
<%= render '/likes/like_button', music: music %>
</div>
</div>
<div class="text-center">
<p class="text-md flex flex justify-center">該当する楽曲が見つかりませんでした。</p>
</div>
<% end %>
</div>
create, destroyアクションのredirect_back ...を削除する
redirect_back
を削除することで、処理がJSファイルへと移動します。
app/controllers/likes_controller
class LikesController < ApplicationController
#省略
def create
@like_music = Like.new(user_id: current_user.id, music_id: params[:format])
@like_music.save
redirect_back fallback_location: search_result_index_path #ここを削除する
end
def destroy
@like_music = current_user.likes.find_by(music_id: params[:id])
current_user.unlikes_music(@like_music)
redirect_back fallback_location: search_result_index_path, success: t('.success') #ここを削除する
end
end
Ajax用のcreate, destroyファイルを作成する
最後にcreate, destroyアクションで使用するJSファイルを作成します。
作成する際は、views/コントローラー名/アクション名.js.erb
でファイルを作成するので注意!
app/views/likes/create.js.erb
id = "<%= @like_music.music_id %>";
target = document.querySelector(`#favorite_button_${id}`);
html = "<%= j(render 'likes/like_button', music: @like_music.music_id) %>";
target.innerHTML = html;
app/views/likes/destroy.js.erb
id = "<%= @like_music.music_id %>";
target = document.querySelector(`#favorite_button_${id}`);
html = "<%= j(render 'likes/like_button', music: @like_music.music_id) %>";
target.innerHTML = html;
ここまでファイルを変更すれば、楽曲をお気に入り登録した際に画面が再レンダリングされることなく、ハートマークの色が変わることが確認できると思います。