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の非同期いいねの方法

Last updated at Posted at 2022-09-06

今回はRailsの非同期いいねの方法について紹介します。

参考記事
https://zenn.dev/odentravel/books/e69a157daeecb3/viewer/b583e5
https://zenn.dev/odentravel/books/e69a157daeecb3/viewer/6d1551

同期いいねの作成

参考記事では、postとuserの紐付けになっていますが、自分はrecruitmentとuserの紐付けになります。
最初にmodelを作成して、dbマイグレイトを行います。

rails g model Favorite user_id:integer recruitment_id:integer
rails db:migrate

次にアソーシエーションの設定をします。

#models/user.rb

class User < ApplicationRecord
#〜省略〜
  has_many :favorites, dependent: :destroy
end

#models/recruitment.rb

class Recruitment < ApplicationRecord
#〜省略〜
  has_many :favorites, dependent: :destroy

  def favorited_by?(user)
    favorites.where(user_id: user.id).exists?
  end
end

favorited_by?では、誰がいいねしたのかを判別します。

#models/favorite.rb
class Favorite < ApplicationRecord
  belongs_to :user
end

これで設定が完了しました。
その次にコントローラーを作成します。

$ rails g controller Favorites

そして、コントローラーを記述します。
内容としては、recruitmentの記事を特定して、ログインユーザーがいいねしたのを保存 or 削除するという処理です。
この時点では、リダイレクトの処理を記述します。

#FavoritesController.rb
class FavoritesController < ApplicationController
def create
  @recruitment = Recruitment.find(params[:recruitment_id])
  favorite = current_user.favorites.new(recruitment_id: @recruitment.id)
  favorite.save
  redirect_to recruitment_path(recruitment)
end

def destroy
  @recruitment = Recruitment.find(params[:recruitment_id])
  favorite = current_user.favorites.find_by(recruitment_id: @recruitment.id)
  favorite.destroy
  redirect_to recruitment_path(recruitment)
end
end

そしてViewを作成します。
この時、いいね作成は、 method: :post にします。
(自分は間違って、method: :recruitment にしてしまい、エラーが出てしまいました。)

#show.html.erb
          <td>
			<p class="caption"><%= recruitment.locate %>
    <% if @recruitment.favorited_by?(current_user) %>
    <%= link_to recruitment_favorites_path(@recruitment), method: :delete, class: "favorite_btn" do %>
      ♥<%= @recruitment.favorites.count %> いいね
    <% end %>
    <% else %>
      <%= link_to recruitment_favorites_path(@recruitment), method: :post, class: "favorite_btn" do %>
      ♡<%= @recruitment.favorites.count %> いいね
      <% end %>
    <% end %>
    </p>	</td>

これで同期いいねの完成です。

非同期いいねの作成

その次にいよいよ非同期いいねの作成に入ります。

最初にlink_toにremote: trueを追記します。これで非同期通信になります。

#show.html.erb
          <td>
					<p class="caption"><%= recruitment.locate %>
    <% if @recruitment.favorited_by?(current_user) %>
    <%= link_to recruitment_favorites_path(@recruitment), method: :delete, remote: true, class: "favorite_btn" do %>
      ♥<%= @recruitment.favorites.count %> いいね
    <% end %>
    <% else %>
      <%= link_to recruitment_favorites_path(@recruitment), method: :post,remote: true,  class: "favorite_btn" do %>
      ♡<%= @recruitment.favorites.count %> いいね
      <% end %>
    <% end %>
    </p>	</td>

その次に、部分テンプレート化します。

#favorite/_favorite.html.erb
          <td>
					<p class="caption"><%= recruitment.locate %>
    <% if recruitment.favorited_by?(current_user) %>
    <%= link_to recruitment_favorites_path(recruitment), method: :delete, remote: true, class: "favorite_btn" do %>
      ♥<%= recruitment.favorites.count %> いいね
    <% end %>
    <% else %>
      <%= link_to recruitment_favorites_path(recruitment), method: :post,remote: true,  class: "favorite_btn" do %>
      ♡<%= recruitment.favorites.count %> いいね
      <% end %>
    <% end %>
    </p>
					</td>

そして、表示部分を下記のように書き換えます。

#favorite/show.html
			<div id="favorite_btn_<%= @recruitment.id %>">
  <%= render 'favorites/favorite', recruitment: @recruitment %>
			</div>

次に非同期処理を実現するためのjsファイルを作成します。

#favorite/create.js.erb
$('#favorite_btn_<%= @recruitment.id %>').html("<%= j(render partial: 'favorites/favorite', locals: {recruitment: @recruitment}) %>");

#favorite/destroy.js.erb
$('#favorite_btn_<%= @recruitment.id %>').html("<%= j(render partial: 'favorites/favorite', locals: {recruitment: @recruitment}) %>");

処理の意味としては、ボタンが押された時、favorites/favoriteを再レンダーするという意味になります。

最後リダイレクトの削除と@をつけます。

class FavoritesController < ApplicationController
def create
  @recruitment = Recruitment.find(params[:recruitment_id])
  favorite = current_user.favorites.new(recruitment_id: @recruitment.id)
  favorite.save
end

def destroy
  @recruitment = Recruitment.find(params[:recruitment_id])
  favorite = current_user.favorites.find_by(recruitment_id: @recruitment.id)
  favorite.destroy
end
end


これで非同期いいね機能の完成です。

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?