【Rails】ルーティングをネストした時にshallowオプションを使うと便利


ネストしたルーティングにshallowオプションを使うと便利だよ！と知ったので、自分なりに記述してみます💪

## ルーティングをネストする

- このような親子関係のモデルがあるとする。
 - Boardモデルが`has_many :comments`
 - Commentモデルが`belongs_to :board`

以下の記述は、ルーティングをネストすることで、掲示板(Board)とコメント(Comment)の親子関係をルーティングで表しています。

```config/routes.rb
resources :boards do
  resources :comments
end
```


次にターミナルで`rails routes`を実行し、利用可能なルーティングをすべて表示してみます。

- `rails routes`で確認できる情報
 - ルーティング名 (あれば)
 - 使用されているHTTP動詞 (そのルーティングがすべてのHTTP動詞に応答するのでない場合)
 - マッチするURLパターン
 - そのルーティングで使うパラメータ

```terminal
$ 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`を付けてあげます。

```config/routes.rb
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)