ネストしたルーティングにshallowオプションを使うと便利だよ!と知ったので、自分なりに記述してみます💪
ルーティングをネストする
- このような親子関係のモデルがあるとする。
- Boardモデルが
has_many :comments
- Commentモデルが
belongs_to :board
以下の記述は、ルーティングをネストすることで、掲示板(Board)とコメント(Comment)の親子関係をルーティングで表しています。
resources :boards do
resources :comments
end
次にターミナルでrails routes
を実行し、利用可能なルーティングをすべて表示してみます。
-
rails routes
で確認できる情報 - ルーティング名 (あれば)
- 使用されているHTTP動詞 (そのルーティングがすべてのHTTP動詞に応答するのでない場合)
- マッチするURLパターン
- そのルーティングで使うパラメータ
$ rails routes
board_comments GET /boards/:board_id/comments(.:format) comments#index
POST /boards/:board_id/comments(.:format) comments#create
new_board_comment GET /boards/:board_id/comments/new(.:format) comments#new
edit_board_comment GET /boards/:board_id/comments/:id/edit(.:format) comments#edit
board_comment GET /boards/:board_id/comments/:id(.:format) comments#show
PATCH /boards/:board_id/comments/:id(.:format) comments#update
PUT /boards/:board_id/comments/:id(.:format) comments#update
DELETE /boards/:board_id/comments/:id(.:format) comments#destroy
boards GET /boards(.:format) boards#index
POST /boards(.:format) boards#create
new_board GET /boards/new(.:format) boards#new
edit_board GET /boards/:id/edit(.:format) boards#edit
board GET /boards/:id(.:format) boards#show
PATCH /boards/:id(.:format) boards#update
PUT /boards/:id(.:format) boards#update
DELETE /boards/:id(.:format) boards#destroy
この状態だと、ある掲示板(board)のコメント(comments)の詳細ページをeditしたり、showしたりする時のURLは、
/boards/:board_id/comments/:id/edit
/boards/:board_id/comments/:id
といった風に指定する必要があり、冗長ですね。
shallowオプションの登場
そこで、ネストしたルーティングに、以下の様にshallow: true
を付けてあげます。
resources :boards do
resources :comments, shallow: true
end
$ rails routes
board_comments GET /boards/:board_id/comments(.:format) comments#index
POST /boards/:board_id/comments(.:format) comments#create
new_board_comment GET /boards/:board_id/comments/new(.:format) comments#new
edit_comment GET /comments/:id/edit(.:format) comments#edit
comment GET /comments/:id(.:format) comments#show
PATCH /comments/:id(.:format) comments#update
PUT /comments/:id(.:format) comments#update
DELETE /comments/:id(.:format) comments#destroy
boards GET /boards(.:format) boards#index
POST /boards(.:format) boards#create
new_board GET /boards/new(.:format) boards#new
edit_board GET /boards/:id/edit(.:format) boards#edit
board GET /boards/:id(.:format) boards#show
PATCH /boards/:id(.:format) boards#update
PUT /boards/:id(.:format) boards#update
DELETE /boards/:id(.:format) boards#destroy
すると、index, new, createの3つのアクション(Commentのidを指定しないアクション)はBoardのidを必要としますが、それ以外のアクションは子のidを指定するだけで済むようになりました。
これは、
- index、new、createは、Commentのidを指定しないため、Boardのidを指定しないと、どのBoardに対するものか参照できない。
- show、edit、update、destroyは、Commentのidを指定するため、それだけで一意性を持てるから、Boardのidを指定する必要がない。
と考えると分かりやすいかなと思います!
参照先
Rails のルーティング(https://railsguides.jp/routing.html)