実現したいこと
- いいねの取り消し機能を動作するようにする
いいねの取り消しができず、逆に再度いいねをしたことになってしまい、自分では解決方法が見いだせないので解決策やヒントをご教授いただきたいです。
前提
Rails7でアルバイト求人サービスで作っており、こちらの記事を参考に「掲載されたお仕事(job)へのいいね(like)」機能を実装しています。
ログイン中のユーザーが、そのお仕事をいいねしていなければ「いいね!ボタン」を表示し、既にいいねしていれば「いいねを取り消すボタン」を表示し、いいねを取り消せるようにしたいです。
userテーブル
、jobテーブル
、likeテーブル
があり、どのuserがどのjobをいいねしたかがlikeテーブル
に保存されるようになっています。
発生している問題・エラーメッセージ
app/views/jobs/show.html.erb
に「いいねを取り消すボタン」を配置しましたが、押下しても再度いいねしたことになってしまいます(エラーは出ていません)。
例えば、以下のように現在ユーザー5(user_id:5)
でログインしており、お仕事7(job_id:7)
のお仕事をいいねしている状態で、
likeテーブル
1+----+---------+--------+----------------------------+----------------------------+ 2| id | user_id | job_id | created_at | updated_at | 3+----+---------+--------+----------------------------+----------------------------+ 4| 9 | 5 | 7 | 2023-05-08 04:23:19.496488 | 2023-05-08 04:23:19.496488 |
お仕事7(job_id:7)
のいいねを取り消そうと思い「いいね済ボタン」を押すと以下のように再度いいねした情報が再度likeテーブル
に保存されてしまいます。
+----+---------+--------+----------------------------+----------------------------+ | id | user_id | job_id | created_at | updated_at | +----+---------+--------+----------------------------+----------------------------+ | 9 | 5 | 7 | 2023-05-08 04:23:19.496488 | 2023-05-08 04:23:19.496488 | | 10 | 5 | 7 | 2023-05-08 04:52:42.012388 | 2023-05-08 04:52:42.012388 |
該当のソースコード
ruby:app/controllers/application_controller.rb
1class ApplicationController < ActionController::Base 2 helper_method :current_user 3 before_action :set_current_user 4 5 def set_current_user 6 @current_user = User.find_by(id: session[:user_id]) 7 end 8 9 private 10 11 def current_user 12 # @current_user ||= User.find_by(id: session[:user_id]) if session[:user_id] 13 end 14end
ruby:app/models/like.rb
1class Like < ApplicationRecord 2 belongs_to :user 3 belongs_to :job 4end
ruby:app/models/user.rb
1class User < ApplicationRecord 2 validates :name, presence: true, length: { maximum: 50 } 3 validates :email, presence: true, length: { maximum: 100 }, uniqueness: true 4 # validates :password_digest, presence: true 5 # has_secure_password 6 # validates :password, length: { minimum: 6 } 7 has_many :likes, dependent: :destroy 8end
ruby:app/models/job.rb
1class Job < ApplicationRecord 2 validates :salary, presence: true, length: { maximum: 5 } 3 has_many :likes, dependent: :destroy 4 5 def liked_by?(user) 6 likes.exists?(user_id: user.id) 7 end 8end
ruby:config/routes.rb
1Rails.application.routes.draw do 2 # resources :jobs 3 root "home#top" 4 resources :users, only: [:new, :create, :edit, :destroy, :update] 5 resources :jobs, only: [:new, :create, :edit, :index, :show, :destroy] do 6 resource :likes, only: [:create, :destroy] 7 end 8 # post "users/create" => "users#create", as: "create_users" 9 # get "users/:id/edit" => "users#edit", as:"edit_users" 10 # post "users/:id/update" => "users#update", as:"update_users" 11 get "signup", to: "users#new", as: "new_users" 12 resources :guest_sessions, only: [:create] 13 # post "guest_login", to: "guest_sessions#guest_login" 14 # get "guest_login", to: "guest_sessions#guest_login" 15 post "logout" => "sessions#destroy" 16 # get "logout" => "sessions#destroy" 17 get "login", to: "sessions#new", as: "new_sessions" 18 post "login", to: "sessions#create", as: "create_sessions" 19 delete "logout", to: "sessions#destroy", as: "destroy_sessions" 20 # get "users/:id/destroy", to: "users#destroy" 21 # delete "users/:id/destroy", to: "users#destroy", as: "destroy_users" 22end
ruby:app/controllers/likes_controller.rb
1class LikesController < ApplicationController 2 # before_action :authenticate_user 3 4 def create 5 # @like = Like.new(user_id: @current_user.id, job_id: params[:job_id]) 6 # @like = Like.new(like_params) 7 # @like.save 8 job = Job.find(params[:job_id]) 9 @current_user.likes.create(job_id: job.id) 10 redirect_to jobs_path 11 end 12 13 def destroy 14 # @like = Like.find_by(like_params) 15 # @like.destroy 16 job = Job.find(params[:job_id]) 17 like = @current_user.likes.find_by(job_id: job.id) 18 like.destroy 19 redirect_to jobs_path 20 end 21 22 private 23 def like_params 24 { user_id: @current_user.id, job_id: params[:job_id] } 25 end 26end
ruby:app/views/jobs/show.html.erb
1<%= @job.salary %> 2<%= link_to("お仕事を編集する", edit_job_path) %> 3<%= button_to "お仕事を削除する", job_path(@job), method: :delete %> 4 5<% if @job.liked_by?(@current_user) %> 6 <%= button_to "いいねを取り消す", job_likes_path(@job), data: { turbo_method: :delete } %> 7<% else %> 8 <%= button_to "いいね!", job_likes_path(@job), data: { turbo_method: :post } %> 9<% end %>
試したこと
参考記事とルーティングを見比べましたが、
参考記事では
resources :posts, only: [:new, :create, :index, :show, :destroy] do
としており、
私は
resources :jobs, only: [:new, :create, :edit, :index, :show, :destroy] do
というようにeditアクション
を加えているだけなので特に問題につながるところではないと思います。
その他では問題の発生箇所となるようなところはわかりませんでした。
補足情報(FW/ツールのバージョンなど)
Ruby3.1.3
Rails7

回答2件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。