はじめに
ある投稿に対していいね機能を実装する際にAjaxを使って一部だけ情報更新を行いたい。
その際、とても苦労した部分について下記の記事にまとめたので、参照していただきたい。
下記テーブルは作成済み。
userテーブル
postテーブル
No | 項目 | 内容 |
---|---|---|
1 | OS | Mac |
2 | Ruby | 2.6.3 |
3 | rails | 6.0.4 |
いいね機能にAjaxを実装
まず、routesを設定する。
resources :posts do
resource :favorites, only: [:create, :destroy]
end
postモデルにfavorite_usersメソッドを追加する。
has_many :favorites, dependent: :destroy
# 下記を追加
has_many :favorite_users, through: :favorites, source: :user
いいねした人を表示するために、@favorite_users
を追加する。
def show
@post = Post.find(params[:id])
# 下記を追加
@favorite_users = @post.favorite_users
postモデルのshowページからいいねをする機能をつける。
<%# いいね機能 %>
<span id="favorite_icon_<%= @post.id %>">
<% unless current_user?(@user) %>
<% if @post.favorited?(current_user) %>
<%= render 'favorites/favorited_state', post: @post %>
<% else %>
<%= render 'favorites/unfavorited_state', post: @post %>
<% end %>
<% end %>
</span>
<span id="favorite_count" class="middle-size"><%= @post.favorites.count %></span>
<p class="margin-top">いいねしたユーザー</p>
<ol id="favorite_user">
<%= render partial: 'favorites/favorite_user', favorite_users: @favorite_users %>
</ol>
いいねアイコン(favorite_icon)を押されると、favoriteコントローラーのcreateアクションまたはdestroyアクションが反応する。
class FavoritesController < ApplicationController
def create
@post = Post.find(params[:post_id])
favorite = current_user.favorites.create(post_id: @post.id)
favorite.save
# redirect_to post_path(params[:post_id]) <=Ajaxを使用するためにここを削除
@favorite_users = @post.favorite_users
respond_to do |format|
format.html { redirect_to @post }
format.js # XHLリクエストが来たら、特定のjsを反応させる
# => default: app/views/favorites/create.js.erb
end
end
def destroy
@post = Post.find(params[:post_id])
favorite = current_user.favorites.find_by(post_id: @post.id)
favorite.destroy
# redirect_to post_path(params[:post_id]) <=Ajaxを使用するためにここを削除
@favorite_users = @post.favorite_users
respond_to do |format|
format.html { redirect_to @post }
format.js
# => default: app/views/favorites/destroy.js.erb
end
end
end
アクションの実行内容を部分的に更新するために、create.jsとdestroy.jsファイルを作成する。
それは、いいねボタン(favorite_icon)と、いいね数(favorite_count)と、いいねした人(favorite_user)を更新する。
$("#favorite_icon_<%= @post.id %>").html("<%= escape_javascript(render('favorites/favorited_state', post: @post)) %>");
$("#favorite_count").html('<%= @post.favorites.count %>');
$("#favorite_user").html('<%= escape_javascript(render('favorites/favorite_user', favorite_user: @favorite_users)) %>');
$("#favorite_icon_<%= @post.id %>").html("<%= escape_javascript(render('favorites/unfavorited_state', post: @post)) %>");
$("#favorite_count").html('<%= @post.favorites.count %>');
$("#favorite_user").html('<%= escape_javascript(render('favorites/favorite_user', favorite_users: @favorite_users)) %>');
パーシャルを作成する
先ほど、showページとjsファイルでrenderするパーシャルを作成していく。
・favorite_iconを表示する。
いいねをした後の状態(createアクション後)
<%= link_to post_favorites_path(post.id), class: "btn", method: :delete, remote: true do %>
<i class="fa-solid fa-thumbs-up fa-3x"></i>
<% end %>
いいねをする前の状態(destroyアクション後)
<%= link_to post_favorites_path(post), class: "btn", method: :post, remote: true do %>
<i class="fa-regular fa-thumbs-up fa-3x"></i>
<% end %>
・いいねした人(favorite_user)を表示するために、パーシャルを作る。
<% @favorite_users.each do |favorite_user| %>
<div><%= favorite_user.name %></div>
<% end %>
おわりに
Ajaxでいいね機能を実装することができた。