はじめに
個人でアプリを開発していてわかったことを今回記事にしました。
状況によっては異なる場合がございます。
開発環境
pc: macOS Catalina
shell: zsh
rails: 6.0.0
ruby: 2.7.2
エラー内容
controller処理でfindメソッドがIDがないと警告を出しています。
itemテーブルの情報を取得する記述をしています。
仮説
①ルーティングの影響により記述が間違えていることによりパラメーターのIDを取得することができない
②ビューのURLに引数として指定されたIDが引き渡しができていないことでIDがないと言っている。
結論
今回のエラーの解決方法にはルーティングのネストの影響が関係していました。
ルーティングをネストすることで、IDが変わってしまうと言うことです。
Rails.application.routes.draw do
devise_for :users
root to: "items#index"
resources :items do
resources :orders , only: [:index, :create]
end
end
% rail routes
root GET / items#index
item_orders GET /items/:item_id/orders(.:format) orders#index
POST /items/:item_id/orders(.:format) orders#create
items GET /items(.:format) items#index
POST /items(.:format) items#create
new_item GET /items/new(.:format) items#new
edit_item GET /items/:id/edit(.:format) items#edit
item GET /items/:id(.:format) items#show
PATCH /items/:id(.:format) items#update
PUT /items/:id(.:format) items#update
DELETE /items/:id(.:format) items#destroy
解説
items controllerでURIは/items/:id(.:format)となっています。
そのため、@item = Item.find(params[:id])とすることでIDが取得することができます。
しかし、Prefixのitem_ordersをみてみるとURIには/items/:item_id/orders(.:format)となっており
IDが変化してしまっています。ですので上記のように記述をしてしまうと、エラーを引き起こしてしまうのです。
@item = Item.find(params[:item_id])とすることでルーティングのURIのIDが一致し取得することができます。
ここから、ネストすることの意味も把握する必要があるのだなと実感しました。
参考文献
・ Ruby on Rails 著:小餅 良介
・ 達人に学ぶDB設計徹底指南書 著:ミック