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