こんにちは!kossyです!
いいね周り実装する時に、
めっちゃハマったのでブログに残したいと思います。。。
話を簡潔にするために一部ロジックを省いて記載しています。
前提情報
User, Product, Likeというモデル定義で、
User has_many products
User has_many likes
Product has_many likes
という構成にしていました。
また、投稿詳細画面からいいねの登録、削除ができるように実装しました。
いいね周りのコードは、
config/routes.rb Rails.application.routes.draw do devise_for :users post "likes/:product_id/create" => "likes#create" post "likes/:product_id/destroy" => "likes#destroy" resources :products, only: [:show] end /views/products/show.html.haml = link_to("お気に入りから削除", "/likes/#{@product.id}/destroy", method: :post) = link_to("お気に入り登録", "/likes/#{@product.id}/create", method: :post) /controller/products_controller.rb def show @product = Product.find(params[:id]) end /controller/likes_controller.rb def create @like = current_user.likes.build(product_id: params[:product_id]) if @like.save redirect_to product_path(@like.product_id) else flash[:notice] = "お気に入りの登録に失敗しました" end end def destroy like = current_user.likes.find_by(product_id: params[:product_id]) if like.destroy redirect_to likes_user_path(current_user) else flash[:notice] = "お気に入りの削除に失敗しました" end end
という感じにしていました。
ここでメンターさんから、
「resourcesを使って実装しましょう」と指令が出たため、
routes.rb Rails.application.routes.draw do devise_for :users resources :products, only: [:show] do resources :likes, only: [:create, :destroy] end end /views/products/show.html.haml = link_to("お気に入りから削除", product_like_path(@product), method: :post) = link_to("お気に入り登録", product_likes_path(@product), method: :post)
という記述に変更。
これで大丈夫かと思ってました。
しかし、、、
ここで動作確認をしたところ、
いいねの登録はできたものの、削除になると、
localhost:3000/products/1/likes/1 Routing Error No route matches [POST] "/products/1/likes/1"
と怒られてしまいました。
likesのidが正しく取得できていないと思い、
ローカル変数としてlikeを定義し、pathの引数にlikeを入れて再チャレンジしたものの、
localhost:3000/products/1/likes/10 Routing Error No route matches [POST] "/products/1/likes/10"
と怒られてしまいました。
rails routesちゃんと見ようね。
likesの値は取得できているのになんで削除できないんだろうと考え、
method: :postとなっていた部分をmethod: :deleteに変えたところ、
ようやく削除に成功しました。。。
rails routesで確認すると、
product_likes POST /products/:product_id/likes(.:format) likes#create product_like DELETE /products/:product_id/likes/:id(.:format) likes#destroy
ちゃんとDELETEを指定しろって書いてありました。。。
みなさん絶対マネしちゃダメ
このようなくだらないミスをする人を一人でも減らすために本エントリを書きました。
みなさん、いいねの削除機能を実装するときはmethod: :deleteにするのを忘れないようにしましょう(棒)