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

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

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

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

Q&A

解決済

1回答

1439閲覧

Couldn't find *** without an IDというエラーに困っております

hirome5

総合スコア2

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

0グッド

0クリップ

投稿2020/06/19 04:17

Couldn't find *** without an IDというエラーについて

お世話になります。
現在、railsでtwitterクローンを作成中です。
フォロー機能に加えて、お気に入り機能を追加しようとしております。

上記お気に入り機能を実装中に以下のエラーメッセージが発生しました。

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

ActiveRecord::RecordNotFound in FavoritesController#create
Couldn't find Minipost without an ID
エラーメッセージ
Couldn't find Minipost without an ID
Extracted source (around line #5):
4def create
5 @minipost = Minipost.find(params[:minipost_id])
6 current_user.like(minipost)
7 flash[:success] = 'このメッセージをお気に入りにしました'
8 redirect_back(fallback_location: root_path)
app/controllers/favorites_controller.rb:5:in `create'

Request
Parameters:

{"utf8"=>"✓", "authenticity_token"=>"s8/u2oD4WEXwIo/Qu7gUiKBNPOdr44g1Fp2SaaoPX6dEhh6yrSrFWNesapJiBDPXEUEfGMvY9OXswX8qNtp22A==", "user_id"=>"", "commit"=>"Like"}

該当のソースコード

ruby

1class User < ApplicationRecord 2 before_save { self.email.downcase! } 3 validates :name, presence: true, length: {maximum:50} 4 validates :email, presence: true, length: {maximum:255}, 5 format: {with:/\A[\w+\-.]+@[a-z\d\-.]+.[a-z]+\z/i }, 6 uniqueness: {case_sesitive: false} 7 has_secure_password 8 has_many :miniposts 9 has_many :relationships 10 has_many :followings, through: :relationships, source: :follow 11 has_many :reverses_of_relationship, class_name: 'Relationship', foreign_key: 'follow_id' 12 has_many :followers, through: :reverses_of_relationship, source: :user 13 has_many :favorites, dependent: :destroy 14 has_many :likes, through: :favorites, source: :minipost 15 16 def follow(other_user) 17 unless self == other_user 18 self.relationships.find_or_create_by(follow_id: other_user.id) 19 end 20 end 21 22 def unfollow(other_user) 23 relationship = self.relationships.find_by(follow_id: other_user.id) 24 relationship.destroy if relationship 25 end 26 27 def following?(other_user) 28 self.followings.include?(other_user) 29 end 30 31 def feed_miniposts 32 Minipost.where(user_id: self.following_ids + [self.id]) 33 end 34 35 36 def like(other_minipost) 37 favorites.find_or_create_by(other_minipost, minipost.id) 38 end 39 40 def unlike(other_minipost) 41 favorite = favorites.find_by(other_minipost, minipost.id) 42 favorite.destroy if favorite 43 end 44 45 def like?(other_minipost) 46 likes.include?(other_minipost) 47 end 48end 49

ruby

1class UsersController < ApplicationController 2 before_action :require_user_logged_in, only: %i(index show followings followers likes) 3 4 def index 5 @users = User.order(id: :desc).page(params[:page]).per(15) 6 end 7 8 def show 9 @user = User.find(params[:id]) 10 @miniposts = @user.miniposts.order(id: :desc).page(params[:page]) 11 counts(@user) 12 end 13 14 def new 15 @user = User.new 16 end 17 18 def create 19 @user = User.new(user_params) 20 21 if @user.save 22 flash[:success] = 'ユーザーを登録しました' 23 redirect_to @user 24 else 25 flash.now[:danger] = 'ユーザーの登録に失敗しました' 26 render :new 27 end 28 end 29 30 def followings 31 @user = User.find(params[:id]) 32 @followings = @user.followings.page(params[:page]) 33 counts(@user) 34 end 35 36 def followers 37 @user = User.find(params[:id]) 38 @followers = @user.followers.page(params[:page]) 39 counts(@user) 40 end 41 42 def likes 43 @minipost = Minipost.find(params[:id]) 44 @likes = @user.likes.page(params[:page]) 45 counts(@user) 46 end 47 48 private 49 50 def user_params 51 params.require(:user).permit(:name, :email, :password, :password_confirmation) 52 end 53 54end

ruby

1class Favorite < ApplicationRecord 2 belongs_to :user 3 belongs_to :minipost 4 5 validates :user, presence: true 6 validates :user_id, uniqueness: { scope: :minipost_id } 7 validates :minipost, presence: true 8end 9

ruby

1class FavoritesController < ApplicationController 2 before_action :require_user_logged_in 3 4 def create 5 @minipost = Minipost.find(params[:minipost_id]) 6 current_user.like(minipost) 7 flash[:success] = 'このメッセージをお気に入りにしました' 8 redirect_back(fallback_location: root_path) 9 end 10 11 def destroy 12 @minipost = Favorite.find(params[:id]).minipost 13 current_user.unlike(minipost) 14 flash[:danger] = 'このメッセージをお気に入りから外しました' 15 redirect_back(fallback_location: root_path) 16 end 17end

ruby

1class Minipost < ApplicationRecord 2 belongs_to :user 3 4 validates :content, presence: true, length: {maximum:255} 5 6 has_many :favorites, dependent: :destroy 7 has_many :likes, through: :favorites, source: :user 8end

ruby

1class MinipostsController < ApplicationController 2 before_action :require_user_logged_in 3 before_action :correct_user, only: %i(destroy) 4 5 def create 6 @minipost = current_user.miniposts.build(minipost_params) 7 if @minipost.save 8 flash[:success] = 'メッセージを投稿しました' 9 redirect_to root_url 10 else 11 @miniposts = current_user.feed_miniposts.order(id: :desc).page(params[:page]) 12 flash.now[:alert] = 'メッセージの投稿に失敗しました' 13 render 'toppages/index' 14 end 15 end 16 17 def destroy 18 @minipost.destroy 19 flash[:success] = 'メッセージを削除しました' 20 redirect_back(fallback_location: root_path) 21 end 22 23 private 24 25 def minipost_params 26 params.require(:minipost).permit(:content) 27 end 28 29 def correct_user 30 @minipost = current_user.miniposts.find_by(id: params[:id]) 31 unless @minipost 32 redirect_to root_url 33 end 34 end 35end

html

1<% if current_user.like?(minipost) %> 2 <%= form_with(model: current_user.favorites.find_by(user_id: minipost.id), local: true, method: :delete) do |f| %> 3 <%= hidden_field_tag :user_id, minipost.id %> 4 <%= f.submit 'Unlike', class: 'btn btn-danger btn-sm' %> 5 <% end %> 6<% else %> 7 <%= form_with(model: current_user.favorites.create, local: true) do |f| %> 8 <%= hidden_field_tag :user_id, minipost.id %> 9 <%= f.submit 'Like', class: 'btn btn-info btn-sm' %> 10 <% end %> 11<% end %>

ruby

1Rails.application.routes.draw do 2 root to: 'toppages#index' 3 4 get 'login', to: 'sessions#new' 5 post 'login', to: 'sessions#create' 6 delete 'logout', to: 'sessions#destroy' 7 8 get 'signup', to: 'users#new' 9 resources :users, only: %i(index show new create) do 10 member do 11 get :followings 12 get :followers 13 get :likes 14 end 15 end 16 17 resources :miniposts, only: %i(create destroy) do 18 end 19 20 resources :relationships, only: %i(create destroy) 21 resources :favorites, only: %i(create destroy) 22

試したこと

ルーティング⇨いいね!をするボタン(like_button)はusers/id:/likesとしたいため、上記のようにしています。user.rbのlikeメソッドの引数とfavoritesControllerの引数を(user_id, minipost.id)としてみたのですが、エラーは”Couldn't find Minipost with 'id'=”となるだけで解決できずにおります。

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

AWS cloud9
ruby 2.5.3
rails 5.2.4.3

初投稿で拙い記載、不足があるかと思いますが、ご教授いただけますと幸いです。
よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

<%= hidden_field_tag :user_id, minipost.id %>

なぜminipost.id:user_idとしているのでしょうか?
2箇所とも<%= hidden_field_tag :minipost_id, minipost.id %>にすると改善するかと思います。


<%= form_with(model: current_user.favorites.create, local: true) do |f| %>

createになっているのが気になります。newでいいのではないでしょうか?

投稿2020/06/19 05:00

asm

総合スコア15147

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

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

hirome5

2020/06/19 05:22

ご回答いただきありがとうございます。ご指摘の箇所につきましては<%= form_with(model: current_user.favorites.find_by(minipost_id: minipost.id)と2箇所の<%= hidden_field_tag :minipost_id, minipost.id %>のように訂正いたしました。もう1箇所も確かにnewで良いですね。 訂正後、再度出力確認しましたところ、”@minipost = Minipost.find(params[:minipost_id])”の箇所について”Couldn't find Minipost with 'id'=”のエラーとなります。パラメータには"minipost_id"=>"", "commit"=>"Like"}のようにidが空となっているためにエラーだということなのでしょうが、users_controllerのdef likesが誤っているのでしょうか?お分かりになればご指摘いただければと存じます。
asm

2020/06/19 05:37

likesも大分不思議ですが(params[:id]がuserなのかminipostなのかハッキリしない) どうも、このViewの時点でminipostが空なようなので ボタンを表示する側のViewおよびControllerについて提示をお願いします。
hirome5

2020/06/21 01:44

ご回答ありがとうございます。そして、返信が遅くなってしまい申し訳ございません。 表示するViewにつきましては <ul class="list-unstyled"> <% miniposts.each do |minipost| %> <li class="media mb-3"> <img class="mr-2 rounded" src="<%= gravatar_url(minipost.user, { size: 50 }) %>" alt=""> <div class="media-body"> <div> <%= link_to minipost.user.name, user_path(minipost.user) %> <span class="text-muted">posted at <%= minipost.created_at %></span> </div> <div> <p class="mb-0"><%= minipost.content %></p> </div> <div style="display:inline-flex"> <% if current_user == minipost.user %> <%= link_to "Delete", minipost, method: :delete, data: { confirm: "You sure?" }, class: 'btn btn-danger btn-sm' %><%= render 'favorites/like_button' , minipost: @minipost %> <% end %> </div> </div> </li> <% end %> <%= paginate miniposts %> </ul> となりまして、 コントローラは class FavoritesController < ApplicationController before_action :require_user_logged_in def create @minipost = Minipost.find(params[:minipost_id]) current_user.like(minipost) flash[:success] = 'このメッセージをお気に入りにしました' redirect_back(fallback_location: root_path) end def destroy @minipost = Favorite.find(params[:id]).minipost current_user.unlike(minipost) flash[:danger] = 'このメッセージをお気に入りから外しました' redirect_back(fallback_location: root_path) end end になります。 コメントでマークアップ記法の仕方がわかりかねるため、直接の表記となり、読みづらいことかと存じますがご確認をお願いいたします。
asm

2020/06/21 11:35

> <%= render 'favorites/like_button' , minipost: @minipost %> paramsに渡らない問題はここですね。 <%= render 'favorites/like_button' , minipost: minipost %> が正しいかと思います。
hirome5

2020/06/22 01:16

ご回答ありがとうございます。 おかげさまで、表題のエラーが解決いたしました。 別なエラーは出ておりますが、ボタンへの値の受け渡しに詰まっておりましたので大変助かりました。 また何かお訊ねするかもしれませんが、どうぞよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問