0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Railsで「お気に入り機能」をAjaxを用いて実装する

Posted at

今回は、Railsでお気に入り登録機能をAjaxを使って非同期処理化していきます。

おおまかな手順

  1. いいねボタンにremote: true を追加する
  2. ビューファイルに目印となるidを付与する
  3. create, destroyアクションのredirect_back ...を削除する
  4. Ajax用のcreate, destroyファイルを作成する

いいねボタンにremote: true を追加する

いいねボタンは複数のビューで扱うためパーシャルファイルとして定義し、
・ ユーザーがログインしているか
・ ログインユーザーの場合は、いいねしている楽曲があるか
上記2つの条件をもとに分岐表示をしています。
Image from Gyazo

以下の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;

ここまでファイルを変更すれば、楽曲をお気に入り登録した際に画面が再レンダリングされることなく、ハートマークの色が変わることが確認できると思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?