Rails routing（resources/resourceとshallow）

Rails のroutingにいくつかよくわかってないメソッド？optionがあったので、この機会に調べてみた。
# resources/resource

sampleとして以下のようなroutes.rbを作成

```
Rails.application.routes.draw do
  resources :books
  resource :person
end
```

```
rake routes
```
すると以下のルーティングが定義された。

```
                   Prefix Verb   URI Pattern                                                                              Controller#Action
                    books GET    /books(.:format)                                                                         books#index
                          POST   /books(.:format)                                                                         books#create
                 new_book GET    /books/new(.:format)                                                                     books#new
                edit_book GET    /books/:id/edit(.:format)                                                                books#edit
                     book GET    /books/:id(.:format)                                                                     books#show
                          PATCH  /books/:id(.:format)                                                                     books#update
                          PUT    /books/:id(.:format)                                                                     books#update
                          DELETE /books/:id(.:format)                                                                     books#destroy
               new_person GET    /person/new(.:format)                                                                    people#new
              edit_person GET    /person/edit(.:format)                                                                   people#edit
                   person GET    /person(.:format)                                                                        people#show
                          PATCH  /person(.:format)                                                                        people#update
                          PUT    /person(.:format)                                                                        people#update
                          DELETE /person(.:format)                                                                        people#destroy
                          POST   /person(.:format)                                                                        people#create
```

## resources
`resources :books`の場合は

```
                    books GET    /books(.:format)                                                                         books#index
                          POST   /books(.:format)                                                                         books#create
                 new_book GET    /books/new(.:format)                                                                     books#new
                edit_book GET    /books/:id/edit(.:format)                                                                books#edit
                     book GET    /books/:id(.:format)                                                                     books#show
                          PATCH  /books/:id(.:format)                                                                     books#update
                          PUT    /books/:id(.:format)                                                                     books#update
                          DELETE /books/:id(.:format)                                                                     books#destroy
```

## resource
`resource :person`の場合は

```
               new_person GET    /person/new(.:format)                                                                    people#new
              edit_person GET    /person/edit(.:format)                                                                   people#edit
                   person GET    /person(.:format)                                                                        people#show
                          PATCH  /person(.:format)                                                                        people#update
                          PUT    /person(.:format)                                                                        people#update
                          DELETE /person(.:format)                                                                        people#destroy
                          POST   /person(.:format)                                                                        people#create
```

`controller#index`がないだけの違いだった。
resourcesは複数あるリソースを対象としているのに対して、resourceは単数を想定しているために `index`がないのだろう。

## shallow

ルーティングはネストさせることができます。
例えばこんな感じです。

```routes.rb
  resources :author do
    resources :books
  end
```

```
             author_books GET    /author/:author_id/books(.:format)                                                       books#index
                          POST   /author/:author_id/books(.:format)                                                       books#create
          new_author_book GET    /author/:author_id/books/new(.:format)                                                   books#new
         edit_author_book GET    /author/:author_id/books/:id/edit(.:format)                                              books#edit
              author_book GET    /author/:author_id/books/:id(.:format)                                                   books#show
                          PATCH  /author/:author_id/books/:id(.:format)                                                   books#update
                          PUT    /author/:author_id/books/:id(.:format)                                                   books#update
                          DELETE /author/:author_id/books/:id(.:format)                                                   books#destroy
             author_index GET    /author(.:format)                                                                        author#index
                          POST   /author(.:format)                                                                        author#create
               new_author GET    /author/new(.:format)                                                                    author#new
              edit_author GET    /author/:id/edit(.:format)                                                               author#edit
                   author GET    /author/:id(.:format)                                                                    author#show
                          PATCH  /author/:id(.:format)                                                                    author#update
                          PUT    /author/:id(.:format)                                                                    author#update
                          DELETE /author/:id(.:format)                                                                    author#destroy
```

こうするとネストがかなり深くて、複雑な部分があります。
このネストを少しでも解消するために、コレクション（idを持たない要素, index/new/create）だけを親要素の下に作り、メンバー（idを必要とする要素、 destroy/update/show）をネストに含めないという方法を取ることができます。


```routes.rb
  resources :author do
    resources :books, shallow: true
  end
```

```
             author_books GET    /author/:author_id/books(.:format)                                                       books#index
                          POST   /author/:author_id/books(.:format)                                                       books#create
          new_author_book GET    /author/:author_id/books/new(.:format)                                                   books#new
                edit_book GET    /books/:id/edit(.:format)                                                                books#edit
                     book GET    /books/:id(.:format)                                                                     books#show
                          PATCH  /books/:id(.:format)                                                                     books#update
                          PUT    /books/:id(.:format)                                                                     books#update
                          DELETE /books/:id(.:format)                                                                     books#destroy
             author_index GET    /author(.:format)                                                                        author#index
                          POST   /author(.:format)                                                                        author#create
               new_author GET    /author/new(.:format)                                                                    author#new
              edit_author GET    /author/:id/edit(.:format)                                                               author#edit
                   author GET    /author/:id(.:format)                                                                    author#show
                          PATCH  /author/:id(.:format)                                                                    author#update
                          PUT    /author/:id(.:format)                                                                    author#update
                          DELETE /author/:id(.:format)                                                                    author#destroy
```