昨日の記事の以下について、今日学びがあったので忘れないうちに書き留めます。
onを省略することもできます。
その場合は、リソースidの値の取得に
params[:id]
ではなくparams[:xxxxxx_id]
を使う点が異なります。ルーティングヘルパーも、zzzzzz_xxxxxx_url
がxxxxxx_zzzzzz_url
に、zzzzzz_xxxxxx_
path
がxxxxxx_zzzzzz_
path
にそれぞれリネームされます。
:on オプションの有無でparamsで取得されるidが変わる
on: :member がある場合
❯ rails routes -c aaaaa_controller -E --[ Route 1 ]-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Prefix | aaaaa_xxxxxxxxxx_yyyyyys_yyyyyy_xxxxxxxxxx Verb | PATCH URI | /xxxxxxxxxx/yyyyyys/:yyyyyy_slug/yyyyyy_xxxxxxxxxx/:id/role(.:format) Controller#Action | xxxxxxxxxx/yyyyyys/yyyyyy_xxxxxxxxxxs/aaaaa#update Source Location | config/routes.rb:115
on: :member がない場合
michi on change_administrator [$⇕] via 🐳 colima via 🦕 v1.37.2 via v18.18.0 via 💎 v3.2.2 took 10s ❯ rails routes -c part_controller -E --[ Route 1 ]-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Prefix | xxxxxxxxxx_yyyyyy_yyyyyy_xxxxxxxxxx_aaaaa Verb | PATCH URI | /xxxxxxxxxx/yyyyyys/:yyyyyy_slug/yyyyyy_xxxxxxxxxxs/:yyyyyy_xxxxxxxxxx_id/aaaaa(.:format) Controller#Action | xxxxxxxxxx/yyyyyys/yyyyyy_xxxxxxxxxxs/aaaaa#update Source Location | config/routes.rb:115
chatGPTに聞いてみる
将来的にどのような差異が生まれるか気になり、chatGPTでは以下の回答を得ました。
========================
on: :memberオプションを付けるか付けないかによってRailsのルーティングが挙動を変えます。
まず基本的に、RailsのルーティングではURLからパラメータを自動的に取得し、そのパラメータはparams
というハッシュに格納されます。
:idは一般的にレコードを特定するための主キーです。リソースのshow, edit, update, destroyなどのアクションでは、それらのアクションを行う特定のレコードに対して行うため、params[:id]
と記述してそのidを取得します。
例えば、/users/1/edit
というURLがあった場合、params[:id]
は1
になります。
ここでon: :member
を付けてルーティングを設定すると、params[:id]
としてidを取得することができます。
一方、:xxxxx_id
の形式はネストされたリソースの場合や、特定のパラメータが必要な場合に使用されます。
以下にその例をあげます:
ruby
resources :users do
resources :posts
end
このようにネストされたリソースが設定されている場合、/users/1/posts/2
というURLがあり、そのURLのコントローラーでparamsを取得すると:
- params[:user_id] は 1
- params[:id] または params[:post_id] は 2
となります。
そのため、:xxxxx_id
は一つ上のリソースを特定するためのパラメータとして使用されることが多いです。なお、:id
と:xxxxx_id
を混同しないように注意が必要です。
また、on: :collection
オプションが設定されていると、そのアクションは特定のリソース(つまりid)に対してではなく、リソース全体、つまりcollectionに対するアクションになるため、params[:id]
は使用されません。
以上、:id
と:xxxxx_id
はどのリソースに対してアクションを行うのかによって使い分けていただければと思います。
========================
最初の私の考え onオプションを付与する
今後aaaaaに関する機能を拡張していくのに、どちらが良いのか考えました。
仮に/yyyyyy_xxxxxxxxxxs/:id/aaaaa/:id が必要となったとしても、param[yyyyyy_xxxxxxxxxxs_id]は有効で、 param[id] でaaaaaのidが取得できるなら現状で問題ないのではないかと見通しを立てました。
指摘いただいて気づいたこと
指摘いただいた中で最も「なるほど」と感じた点は「idがすなわちリソースの識別子になっていない」という点でした。
つまり、aaaaaのidであるのに、onオプションを付ける場合にparamsで取得できるidはaaaaaの識別子とはなりません。
この矛盾は読み手を混乱させます。
最初は、リソース名との関連など考えが及んでいませんでした。
コード全体を俯瞰できる視点を持つことの大切さがわかりました。