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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1592閲覧

いいね機能が実装できない

max3252

総合スコア4

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2020/09/10 07:27

前提・実現したいこと

以前、写真投稿型のアプリの詳細ページに非同期でいいね機能を実装しようとしましたが、断念して非同期ではない、いいね機能を実装しようとしています。
いいねボタンを押すと読み込みが発生して、ボタンがいいね済みボタンに切り替わるというものです。逆も可能です。
現在はボタンを押すとエラーになってしまうのでエラーを解消したくて質問しました。
エラー後に直接URL検索で元の投稿詳細ページへ遷移すると反映はされていました。
Qiitaやテラテイル内で同じような問題を参考に色々試しましたがうまくいかないです。
プログラミング初学者のなので、至らない所だらけですが教えていただけると助かります。

発生している問題・エラーメッセージ

#いいねボタンを押すと ActiveRecord::RecordNotFound in LikesController#create Couldn't find Post without an ID
#いいね済みボタンを押すと NoMethodError in LikesController#destroy undefined method `destroy' for nil:NilClass

該当のソースコード

controller

1class LikesController < ApplicationController 2 def create 3 @post = Post.find(params[:id]) 4 @like = current_user.likes.create(post_id: params[:post_id]) 5 redirect_back(fallback_location: root_path) 6 end 7 8 def destroy 9 @post = Post.find(params[:id]) 10 @like = Like.find_by(post_id: params[:post_id], user_id: current_user.id) 11 @like.destroy 12 redirect_back(fallback_location: root_path) 13 end 14end

controller

1class PostsController < ApplicationController 2 def show 3 @like = Like.new 4 end 5end

routes

1Rails.application.routes.draw do 2 devise_for :users 3 root to: "posts#index" 4 resources :posts do 5 resources :comments, only: :create 6 resources :likes, only: [:create, :destroy] 7 end 8

model

1class Like < ApplicationRecord 2 belongs_to :post 3 belongs_to :user 4 5 validates_uniqueness_of :post_id, scope: :user_id 6end 7

model

1class Post < ApplicationRecord 2 belongs_to :user 3 has_many :likes, dependent: :destroy 4 has_many :liked_users, through: :likes, source: :user 5 6 def like_user(user_id) 7 likes.find_by(user_id: user_id) 8 end 9 10end

model

1class User < ApplicationRecord 2 has_many :posts 3 has_many :likes, dependent: :destroy 4 has_many :liked_posts, through: :likes, source: :post 5 6 def already_liked?(post) 7 self.likes.exists?(post_id: post.id) 8 end 9 10end 11 12

html

1 <% if current_user.already_liked?(@post) %> 2 <%= button_to 'いいねを取り消す', post_like_path(@post), method: :delete %> 3 <% else %> 4 <%= button_to 'いいね', post_likes_path(@post) %> 5 <% end %>

試したこと

こちらの記事を参考にさせていただきました。

"https://qiita.com/keitah/items/12b50c86bcfa9cfb4db9"

検索すればいくらでもでてきそうな問題で参考記事もたくさんありますが、自分なりに検索をかけてできなかった問題なのですみませんが宜しくおねがいします。

補足情報(FW/ツールのバージョンなど)

Rails ver 6.0.0

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

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

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

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

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

guest

回答1

0

ベストアンサー

rails routesをするとわかると思いますが、
likeのcreateのURLに:idは存在しません。(今から作る)

そのため
@post = Post.find(params[:id])
params[:id]はnilになりPostが見つからないよ!ってエラー出てます。
もし@postが必要なら

@post = Post.find(params[:post_id])

になります。

2個目のエラーは@likeがnilのためdestroyができてません。
1個目の時にいいねが作れてないか、find_byの部分が間違えているかと思います。

これらを修正してみてください!

投稿2020/09/10 10:22

necocoa

総合スコア209

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

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

max3252

2020/09/10 10:53

ご回答ありがとうございます! さっそくご指摘箇所確認してみます!!
max3252

2020/09/11 00:51

necocoa様のご指摘通りparamsを変更したらうまくいきました! MVCの理解がまだ足りないことを痛感しました。 2個目のエラーに関しては上記の変更をしたらうまくいきました! necocoa様の推測どおりでしたね。。。 適切な解説ほんとうにありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問