2
0

More than 3 years have passed since last update.

[rails]"いいね解除"が出てこないエラーのないエラー[解決!]

Last updated at Posted at 2021-08-26

はじめに

本記事は、現在悩んでいることを記述します。
(記述することで、客観視しやすいことも言い訳の一つです)
今回は100%備忘録で申し訳ありません。
もし宜しければ、アドバイスいただけますと幸いです。

いいね機能導入について

いいねをLikeテーブルという名前で作成しております。
こちらを参考に作成していますので、ご参照ください。
Railsでいいね機能を実装しよう

エラー

URL generationエラー(いいね機能).png

コード

routes.rb
Rails.application.routes.draw do

  devise_for :users
  root to: 'foods#index'
  resources :foods do
    collection do
      get :search
    end
    resources :likes, only: [:create, :destroy]
  end
  resources :users, only: :show

end
likes_controller.rb
class LikesController < ApplicationController

  def create
    @like = current_user.likes.create(food_id: params[:food_id])
    redirect_back(fallback_location: root_path)
  end

  def destroy
    @food = Food.find(params[:food_id])
    @like = current_user.likes.find_by(food_id: @food.id)
    @like.destroy
    redirect_back(fallback_location: root_path)
  end
end
like.rb
class Like < ApplicationRecord
  belongs_to :food
  belongs_to :user
  validates_uniqueness_of :food_id, scope: :user_id
end
food.rb
class Food < ApplicationRecord

  belongs_to :user
  has_many :likes
  has_many :liked_users, through: :likes, source: :user
  has_one_attached :image

  def self.search(search)
    if search != ""
      Food.where("food_name LIKE(?)", "%#{search}%")
    else
      Food.all
    end
  end

  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :meal_type
  belongs_to :spicy_level
  belongs_to :shop_mood
  belongs_to :waiting_time

  with_options presence: true do
    validates :image
    validates :shop_name
    validates :food_name
    validates :spicy_level_id
  end
end
user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_many :foods, dependent: :destroy
  has_many :likes, dependent: :destroy
  has_many :liked_foods, through: :likes, source: :food
  has_one_attached :image

  def already_liked?(food)
    self.likes.exists?(food_id: food)
  end
end
foods_controller.rb
class FoodsController < ApplicationController

  def index
    @foods = Food.order("created_at DESC")
    @like = current_user.likes.create(food_id: params[:food_id])
  end

  def new
    @food = Food.new
  end

  def create
    @food = Food.new(food_params)

    if @food.save
      redirect_to root_path
    else
      render :new
    end

  end

  def search
    @foods = Food.search(params[:keyword])
  end

  def edit
    @food = Food.find(params[:id])
    return redirect_to user_path if current_user.id != @food.user.id
  end

  def update
    @food = Food.find(params[:id])
    return redirect_to user_path if current_user.id != @food.user.id

    if @food.update(food_params)
      redirect_to user_path(@food.user_id)
    else
      render :edit
    end
  end

  def show
    @food = Food.find(params[:id])
    @like = Like.new
  end

  def destroy
    @food = Food.find(params[:id])
    return redirect_to user_path if current_user.id != @food.user.id

    @food.destroy
    redirect_to user_path(@food.user_id)
  end

  private

  def food_params
    params.require(:food).permit(:image, :meal_type_id, :shop_name, :shop_name_kana, :food_name, :spicy_level_id, :station, :shop_mood_id, :waiting_time_id, :food_comment).merge(user_id: current_user.id)
  end

end

viewについては2パターン考えました。

該当のviewその①。(エラー画面はこっち)

<% if current_user.already_liked?(food) %>
  <%= link_to "いいねを取り消す", food_like_path(food), method: :delete %>
<% else %>
  <%= link_to "いいね", food_likes_path(food), method: :post %>
<% end %>

該当のviewその②

<% if @like != nil %>
  <%= link_to "いいね解除", food_like_path(food, @like), method: :delete %>
<% else %>
  <%= link_to "いいね", food_likes_path(food), method: :post %>
<% end %>

仮説&考え&現状

いいねボタンは表示されており、Likeテーブルには情報が入っている。つまりいいねはできる。

いいね後、いいね解除のボタンが出てこない。

③if文が悪い?しかし、エラー文を見るに、if文はスルーしてるので、悪くないのでは?

④いいねのパスが正常なら解除のパスも正常では?
となるとモデルorコントローラーが原因?

⑤viewその①で「foodから@food」とするとエラーはなくなるが、

<% if current_user.already_liked?(@food) %>

いいねした後、いいね解除が出て来ない。

解決!

routes.rb
Rails.application.routes.draw do

  devise_for :users
  root to: 'foods#index'
  resources :foods do
    collection do
      get :search
    end
    resource :likes, only: [:create, :destroy]
  end
  resources :users, only: :show

end

resource :likes, only: [:create, :destroy]
resourcesの「s」を抜いたところ、
無事にエラー解決しました!!
YATTA!

終わりに

解決していないので、正式には終わりにというわけではありませんが、
なんとか解決したいと思います。

引き続き頑張ろ!!!!

参考サイト
【Rails】いいね機能:いいねを取り消す際、いいね数が0になるまで減少できてしまう
ActionController::UrlGenerationError(いいねボタンのmethod:delete)
Railsでいいね機能を実装しよう
railsにていいね機能実装中 ActionController::UrlGenerationError in Books#show エラー
いいね機能の作成
【Rails】いいね機能完全版!同期いいね、いいね数の表示、非同期いいね、アイコン表示、それぞれの実装方法についてまとめて解説
いいねの解除ができない
Railsアプリに「いいね機能」を実装する方法
【Rails×Ajax】いいね機能ハンズオン
【Ruby on Rails】いいね機能を作ってみよう(初心者から中級者向け)PART 3(実装③) ~ Let's build with Ruby on Rails ~

2
0
1

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
2
0