1
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.

【Ajax】いいね機能を非同期通信で実装したいよ

Last updated at Posted at 2022-07-03

はじめに

ある投稿に対していいね機能を実装する際にAjaxを使って一部だけ情報更新を行いたい。
その際、とても苦労した部分について下記の記事にまとめたので、参照していただきたい。

下記テーブルは作成済み。
userテーブル
postテーブル

No 項目 内容
1 OS Mac
2 Ruby 2.6.3
3 rails 6.0.4

いいね機能にAjaxを実装

早速実装を開始する。
完成図
完成図.gif

まず、routesを設定する。

routes.rb
  resources :posts do
    resource :favorites, only: [:create, :destroy]
  end

postモデルにfavorite_usersメソッドを追加する。

post.rb
has_many :favorites, dependent: :destroy
# 下記を追加
has_many :favorite_users, through: :favorites, source: :user

いいねした人を表示するために、@favorite_usersを追加する。

posts_controller.rb
def show
    @post = Post.find(params[:id])
# 下記を追加
    @favorite_users = @post.favorite_users

postモデルのshowページからいいねをする機能をつける。

app/views/posts/show.html.erb
<%# いいね機能 %>
<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アクションが反応する。

favorites_controller.rb
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)を更新する。

app/views/favorites/create.js.erb
$("#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)) %>');
app/views/favorites/destroy.js.erb
$("#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アクション後)

favorites/_favorited_state.html.erb
<%= 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アクション後)

favorites/_unfavorited_state.html.erb
<%= 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)を表示するために、パーシャルを作る。

favorites/_favorite_user.html.erb
<% @favorite_users.each do |favorite_user| %>
  <div><%= favorite_user.name %></div>
<% end %>

おわりに

Ajaxでいいね機能を実装することができた。

1
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
1
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?