前書き
正しいルーティングを記載しているのに想定していたコントローラーに繋がらなくハマったので記事に残します。
ハマったこと
new_admin_product(admin/products#new ) というprefixでリクエストを送るとBのadmin/productsコントローラーのnewアクションに遷移すると想定していました。ただ実際はAのproductsコントローラーのshowアクションに遷移してしまう。 上記のルーティングで実際作成されるパスは以下になります↓
| ルート名 | HTTPメソッド | パス | コントローラー#アクション | |---------------------|--------------|------------------------------|-----------------------------| | admin_products | GET | /admin/products(.:format) | products#index | | admin_product | GET | /admin/products/:id(.:format)| products#show ⇦このアクションにつながる | | | POST | /admin/products(.:format) | admin/products#create | | new_admin_product | GET | /admin/products/new(.:format)| admin/products#new ⇦このアクションにつなげたい | | edit_admin_product | GET | /admin/products/:id/edit | admin/products#edit | | | PATCH | /admin/products/:id(.:format)| admin/products#update | | | PUT | /admin/products/:id(.:format)| admin/products#update | | | DELETE | /admin/products/:id(.:format)| admin/products#destroy |
結論
⇨namespace :admin doとscope 'admin' doのルーティングの記載の順番を入れ替える
| ルート名 | HTTPメソッド | パス | コントローラー#アクション | |---------------------|--------------|----------------------------------|-----------------------------| | admin_products | POST | /admin/products(.:format) | admin/products#create | | new_admin_product | GET | /admin/products/new(.:format) | admin/products#new ⇦このアクションにつながる | | edit_admin_product | GET | /admin/products/:id/edit. | admin/products#edit | | admin_product | PATCH | /admin/products/:id(.:format) | admin/products#update | | | PUT | /admin/products/:id(.:format) | admin/products#update | | | DELETE | /admin/products/:id(.:format) | admin/products#destroy | | | GET | /admin/products(.:format) | products#index | | | GET | /admin/products/:id(.:format) | products#show |
解説
new_admin_product(/admin/products/new) というリクエストを送信するとroutes.rbの上から順番に一致するものを探す。
| ルート名 | HTTPメソッド | パス | コントローラー#アクション | |---------------------|--------------|------------------------------|-----------------------------| | admin_products | GET | /admin/products(.:format) | products#index | | admin_product | GET | /admin/products/:id(.:format)| products#show ⇦このアクションにつながる | | | POST | /admin/products(.:format) | admin/products#create | | new_admin_product | GET | /admin/products/new(.:format)| admin/products#new ⇦このアクションにつなげたい | | edit_admin_product | GET | /admin/products/:id/edit | admin/products#edit | | | PATCH | /admin/products/:id(.:format)| admin/products#update | | | PUT | /admin/products/:id(.:format)| admin/products#update | | | DELETE | /admin/products/:id(.:format)| admin/products#destroy |
上のハマったルーティングを見ると
/admin/products/newが/admin/products/:idと一致すると判断されたため想定外のコントローラーのアクションに遷移しました.
なぜなら:idの中にnewが代入される.
:idと聞くとadmin/products/2などのように数値
が入るイメージでしたが数値以外も代入されるそうです
まとめ
ルーティングの記載の順番で想定外のコントローラーにつながる
/admin/products/:idなどの:idには数値以外も代入される
ルーティングは上から順番に一致するものを探す