Oba-eng / curry_web

0 stars 0 forks source link

お気に入り機能でエラーが発生してしまう #24

Open Oba-eng opened 5 months ago

Oba-eng commented 5 months ago

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

<%= link_to menu_path(menu), class: 'menu-card' do %> <% end %>

<%= menu.name %>

<%= menu.material %>

<%= menu.point %>


<%= menu.user.name %>

<% if current_user && current_user.own?(menu) %> <%= render 'favorite_button', menu: menu %> <% else %> <%= render 'favorite_button', menu: menu %> <% end %>

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


- エラーから考えられる原因
パラメーターの受け取りが出来ていないため、ここが原因だと考えてます。

- 試したこと
```favorites_controller.rb:5:in `create'```とあったためコントローラーのパラメーターの部分の書き方を色々変えてみて変化があるか確認しましたが変化がなくイマイチ理解できてないです。

def create menu = Menu.find(params[:menu_id]) current_user.favorite(menu) redirect_back fallback_location: root_path, success: t('defaults.message.bookmark') end



- 参考URL
https://qiita.com/manbolila/items/43a04e8d0d5018cf7f62
上記記事とは別に卒業試験のモクモク会のアプリを参照しました。

- バージョン情報
Rails 6.1.4
ruby 3.0.2
Tsuchiya2 commented 5 months ago
image

飛ばしたいリクエスト先(URL・コントローラー#アクション)に正しくリクエストができているかをログ等から確認して、期待しているリクエストが飛んでいないようであれば、なぜ期待している先にリクエストが飛ばせていないかを考え、仮説立て・検証のサイクルを回してみていただけますか。

Oba-eng commented 5 months ago

お気に入りのcreateは動くようになりました。 今度は削除ボタン(お気に入り解除)をクリックした時にエラーが発生してしまってます。 Image from Gyazo

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>,が存在しているため正しく保存されていることがわかりました。 エラー発生の原因がわからないためアドバイスをいただきたいです。

Tsuchiya2 commented 5 months ago

よくよくエラー等を確認して現状把握を行いましょう。

current_user.favoritesでどんな値が返ってきているのか、返ってきている値に対してfind(params[:id])を行うことで何を行おうとしようとしているのか、渡ってきているparamsの中にidの値はどこに対応する値を渡そうとしているのか確認・仮説立て・検証をしてみてください。

Oba-eng commented 5 months ago

すいません、限界です。

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_userfavorites から要素を見つけようとします。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]以外のコードを変える必要があるのかなと考えてますが、コントローラー以外に変えるところもないので手が止まってます。

Tsuchiya2 commented 5 months ago

切羽詰まった際は一旦対象の問題から離れてみると、アレ?ここってこうじゃないだろうか?というのが浮かんでくるものなので散歩や仮眠などを取り入れるといいらしいです。

話がそれましたが、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>の部分では無いでしょうか?

Oba-eng commented 5 months ago

解決しました!

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モデルに値を探しにいくことになるためエラーが解消されました。 また、ネストなどルーティングについて復習もできたためよかったです。