Open Oba-eng opened 5 months ago
飛ばしたいリクエスト先(URL・コントローラー#アクション)に正しくリクエストができているかをログ等から確認して、期待しているリクエストが飛んでいないようであれば、なぜ期待している先にリクエストが飛ばせていないかを考え、仮説立て・検証のサイクルを回してみていただけますか。
お気に入りのcreateは動くようになりました。 今度は削除ボタン(お気に入り解除)をクリックした時にエラーが発生してしまってます。
Couldn't find Favorite with 'id'=20 [WHERE "favorites"."user_id" = ?]
とあったためuser_idが見つかっていないことでエラーが発生している状況です。
コンソールで調べてみた結果
>> current_user
=> #<User id: 9, name: "テスト", email: "p@example.com", menu_image: nil, created_at: "2024-03-09 08:06:56.798237000 +0000", updated_at: "2024-03-09 08:06:56.798237000 +0000", encrypted_password: "", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, crypted_password: "$2a$10$IHGX0cD0QbIGzg6pG3lPYeRZpGV2j/FBsuaYM5cY5ZQ...", salt: "N4ZfsPVVxzHcpEsUzXCL">
>> params[:id]
=> "20"
current_userはUser id: 9とあるのでidが取得できていると思いますがuser_idとmenu_idが一致しないとなってます。
oobarikuto@MacBook-Air-2 carry_web % bin/rails c
Running via Spring preloader in process 30579
Loading development environment (Rails 6.1.4)
irb(main):001:0> Favorite.all
(0.4ms) SELECT sqlite_version(*)
Favorite Load (0.1ms) SELECT "favorites".* FROM "favorites"
=>
[#<Favorite:0x0000000117d80640 id: 1, user_id: 9, menu_id: 21>,
#<Favorite:0x0000000117d93a10 id: 2, user_id: 9, menu_id: 20>,
#<Favorite:0x0000000117d93948 id: 3, user_id: 9, menu_id: 17>]
正しくfavoriteテーブルに保存が出来ていないかと考え確認しましたが、
#<Favorite:0x0000000117d93a10 id: 2, user_id: 9, menu_id: 20>,
が存在しているため正しく保存されていることがわかりました。
エラー発生の原因がわからないためアドバイスをいただきたいです。
よくよくエラー等を確認して現状把握を行いましょう。
current_user.favoritesでどんな値が返ってきているのか、返ってきている値に対してfind(params[:id])を行うことで何を行おうとしようとしているのか、渡ってきているparamsの中にidの値はどこに対応する値を渡そうとしているのか確認・仮説立て・検証をしてみてください。
すいません、限界です。
current_user.favoritesはログインしているユーザーのfavoriteテーブルを取得する
current_user.favorites
=> #<ActiveRecord::Associations::CollectionProxy [#<Favorite id: 5, user_id: 11, menu_id: 24>, #<Favorite id: 6, user_id: 11, menu_id: 23>]>
current_user.favorites.find(params[:id])
: このコードは、params[:id]
に一致する current_user
の favorites
から要素を見つけようとします。find
メソッドは、指定されたIDに一致する要素が見つからない場合、ActiveRecord::RecordNotFound
エラーを発生させます。
find(params[:id])を行うことで何を行おうとしようとしている? current_userのfavoritesから要素を見つけようとする。
oobarikuto@MacBook-Air-2 carry_web % bin/rails c
Running via Spring preloader in process 32681
Loading development environment (Rails 6.1.4)
irb(main):001:0> Favorite.all
(0.2ms) SELECT sqlite_version(*)
Favorite Load (0.1ms) SELECT "favorites".* FROM "favorites"
=>
[#<Favorite:0x00000001300a7590 id: 1, user_id: 9, menu_id: 21>,
#<Favorite:0x0000000127541af0 id: 2, user_id: 9, menu_id: 20>,
#<Favorite:0x0000000127540c40 id: 3, user_id: 9, menu_id: 17>,
#<Favorite:0x0000000127540a60 id: 4, user_id: 9, menu_id: 24>,
#<Favorite:0x0000000127540448 id: 5, user_id: 11, menu_id: 24>,
#<Favorite:0x0000000127540060 id: 6, user_id: 11, menu_id: 23>,
#<Favorite:0x000000012753be70 id: 7, user_id: 11, menu_id: 17>]
current_user.favorites
=> #<ActiveRecord::Associations::CollectionProxy
[#<Favorite id: 5, user_id: 11, menu_id: 24>,
#<Favorite id: 6, user_id: 11, menu_id: 23>,
#<Favorite id: 7, user_id: 11, menu_id: 17>]>
params[:id]
=> "17"
params[:id]はfavoriteのidを指すらしい。 でも実際に取得しているidはmenu_idっぽい。 id=17のfavoriteはないとエラーが出ている状態。
メモしながら進めてみました。 params[:id]の部分が原因だと思うのですが、期待しているのはfavoriteのid。実際に返ってきているのはmenuのid。 params[:id]がなんでmenuのidを返しているのか、どうしたらfavoriteのidを返してくれるのかがわかりません。 params[:id]をparams[:favorite_id]、params[:favorite_id]に変えてみましたがエラーの内容が変わっていなかったため params[:id]以外のコードを変える必要があるのかなと考えてますが、コントローラー以外に変えるところもないので手が止まってます。
切羽詰まった際は一旦対象の問題から離れてみると、アレ?ここってこうじゃないだろうか?というのが浮かんでくるものなので散歩や仮眠などを取り入れるといいらしいです。
話がそれましたが、findメソッドは何を対象にしてレコードを取得するものでしょうか?レコードの取得はfindだけでしたでしょうか?where, find_byメソッドなどのレコード取得するメソッドを調べて、どのカラムの情報を対象にレコードを取得したいのかを考えてみましょう。
current_user.favorites => #<ActiveRecord::Associations::CollectionProxy [#<Favorite id: 5, user_id: 11, menu_id: 24>,
<Favorite id: 6, user_id: 11, menu_id: 23>,
<Favorite id: 7, user_id: 11, menu_id: 17>]>
params[:id] => "17"
current_user.favorites.find(17)でFavoriteのiD(17)を探すようにコードを書いていますが、欲しい情報は#<Favorite id: 7, user_id: 11, menu_id: 17>
の部分では無いでしょうか?
解決しました!
def destroy
menu = current_user.favorites.find(params[:menu_id])
current_user.unfavorite(menu)
redirect_back fallback_location: root_path, success: t('defaults.message.unbookmark')
end
これだとfindメソッドがfavoriteモデルに値を探しにいくためエラーが発生していました。
def destroy
menu = current_user.favorite_menus.find(params[:menu_id])
current_user.unfavorite(menu)
redirect_back fallback_location: root_path, success: t('defaults.message.unbookmark')
end
こうすることによりfindメソッドがmenuモデルに値を探しにいくことになるためエラーが解消されました。 また、ネストなどルーティングについて復習もできたためよかったです。
質問内容・実現したいこと お気に入りボタンをクリックするとエラーが発生する。
現状発生している問題・エラーメッセージ
どの処理までうまく動いているのか お気に入りボタン(星マーク)の表示まではできています。 中間テーブルやモデルの関連付けの確認もしていて問題なかったです。
該当のソースコード
end
app/views/menus/_favorite_button.html.erb <% if current_user && current_user.favorite?(menu) %> <%= render 'unfavorite', { menu: menu } %> <% else %> <%= render 'favorite', { menu: menu } %> <% end %>
app/views/menus/_favorite.html.erb <%= link_to favorites_path(menu), method: :post do %> <% end %>
app/views/menus/_unfavorite.html.erb <%= link_to favorite_path(menu_id: @menu.id),method: :delete do %> <% end %>
app/views/menus/_menu.html.erb
<%= menu.name %>
<%= menu.material %>
<%= menu.point %>
<%= menu.user.name %>
routes.rb Rails.application.routes.draw do root 'menus#index'
resources :menus do resources :favorites, only: [:create, :destroy] end
resources :users resources :menus do collection do get :favorites end end resources :favorites, only: %i[create destroy]
namespace :mypage do resources :tree, only: [:index] end
resources :sessions, only: [:new, :create, :destroy]
delete 'logout', to: 'sessions#destroy' get 'logout', to: 'sessions#destroy', as: :logout_get
フッターのリンクを作成
get 'privacy', to: 'pages#privacy', as: :privacy get 'terms', to: 'pages#terms', as: :terms
お問い合わせメール
namespace :public do resources :contacts, only: [:new, :create] do collection do post 'confirm' post 'back' get 'done' end end end
end
def create menu = Menu.find(params[:menu_id]) current_user.favorite(menu) redirect_back fallback_location: root_path, success: t('defaults.message.bookmark') end