非同期通信のやり方

2024/03/05に公開

内容

PF作成の時にメンターさんに教えて頂いたことをいつもで引き出せるように書いておこうと思います。

show.html.erb

   :
<div id="favorite-<%= @record.id %>">
  <%= render 'public/favorites/favorite', record: @record %>
</div>
    :

部分テンプレートを読み込む箇所にid名またはclassを記述する

①<div id="favorite-<%= @record.id %>">
②<div class="favorite-<%= @record.id %>">

今回は、ユーザー(current_user)のいいね(favorite)は、レコード(@record)に対してひとつになるため、idを使いました。
idはclassよりも優先順位が高く、複数存在してはいけないものになる為、上記のようなひとつしか使わないものに使います。
逆にclassは複数の要素に適用できるため、複数の要素に同じスタイルや操作を適用したい場合に使用します。

favorites_controller.rb

class Public::FavoritesController < ApplicationController

  def create
    @record = Record.find(params[:record_id])
    favorite = current_user.favorites.new(record_id: @record.id)
    favorite.save
  end

  def destroy
    @record = Record.find(params[:record_id])
    favorite = current_user.favorites.find_by(record_id: @record.id)
    favorite.destroy
  end

end

redirect_toを記載するとhtml.erbファイルを呼び出そうとしてしまうため、記述を削除してます。

_favorite.html.erb

<% if record.favorited_by?(current_user) %>
  <%= link_to study_record_favorites_path(record.study, record), method: :delete, remote: true do %>
    <i class="fa-solid fa-thumbs-up"></i>
  <% end %>
  <span>いいね! (</span>
  <%= record.favorites.count %>
  <span>)</span>
<% else %>
  <%= link_to study_record_favorites_path(record.study, record), method: :post, remote: true do %>
    <i class="fa-regular fa-thumbs-up"></i>
  <% end %>
  <span>いいね! (</span>
  <%= record.favorites.count %>
  <span>)</span>
<% end %>

呼び出し先の部分テンプレートを作成する

remote: true を記載することで、非同期で送信されるようになり、部分テンプレート部分が再読み込み無しで更新されるようになります。

create.js.erb & destroy.js.erb

$('#favorite-<%= @record.id %>').html("<%= j(render 'public/favorites/favorite', record: @record) %>");

今回はidで指定しているため、呼び出し方が'#favorite-<%= @record.id %>'になってます。
classで指定する場合は、'.favorite-<%= @record.id %>'になります。
cssでも同様の書き方になります。

まとめ

idとclassの違いについて、よく分かっておらず、教えて頂いた内容になります。

Discussion