質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails 7

Ruby on Rails 7は、2021年12月に正式リリースされました。Ruby on Railsのバージョン7であり、フロントエンド開発環境を大幅に刷新。Node.jsを用いない構成がデフォルトになっています。

Q&A

解決済

1回答

419閲覧

Rails いいねの取り消しボタンが機能せず再度いいねされてしまう

AIR11451481019

総合スコア9

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails 7

Ruby on Rails 7は、2021年12月に正式リリースされました。Ruby on Railsのバージョン7であり、フロントエンド開発環境を大幅に刷新。Node.jsを用いない構成がデフォルトになっています。

0グッド

0クリップ

投稿2023/05/08 23:33

実現したいこと

  • いいねの取り消し機能を動作するようにする

いいねの取り消しができず、逆に再度いいねをしたことになってしまい、自分では解決方法が見いだせないので解決策やヒントをご教授いただきたいです。

前提

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

likeテーブルにカラム(例:good_flg)を追加するのはいかがでしょうか。

likeテーブルにカラム(列)を追加します。
このカラムはいいね押した状態 or いいね押していない状態 のどちらなのか管理するものです。
一般的には0:押していない、1:押している 状態と定義することが多いです。
私なら、int型のgood_flg(NOT NULL、DEFAULT 0)でカラム追加します。

このテーブルの利用方法の例として、
1.ユーザ(user_id:5)がお仕事(job_id:7)に初めていいねする
→likeテーブルにINSERTでgood_flgが1のレコードが登録される
2.ユーザ(user_id:5)がお仕事(job_id:7)のいいねを取り消す
→likeテーブルのUPDATE(Edit)で該当のレコードのgood_flgを0にする
3.ユーザ(user_id:5)がお仕事(job_id:7)に再びいいねする
→likeテーブルのUPDATE(Edit)で該当のレコードのgood_flgを1にする

また、ユーザ(user_id:5)がお仕事(job_id:7)にいいねしているか否かの状態はlikeテーブルを参照できます。
したがって、View(HTML)側にていいねの状態によってアイコンや動作を変更したい際は上記を利用可能です。

ちなみにですが、お仕事ごとで合計いいね数をカウントしたい際は、WHEREでjob_id=[該当のお仕事のjob_id] AND good_flg=1で取得可能です。

投稿2023/05/09 05:52

Mash

総合スコア40

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AIR11451481019

2023/05/12 08:15

Mashさん、ご回答いただきありがとうございます。 こちらの質問ですが、別の機能を実装したときに同じようなコードを書いたところうまく行ったので、とりあえず解決済みにしたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問