map.resource(s)がURL設計をまとめてくれる
Railsのmap.resource(s)を使うと画面の構成をまとめて記述できます。
例えば、config/routes.rbに以下のように書くと、
ActionController::Routing::Routes.draw do |map| map.resource :sessions map.resources :magazines do |magazine| # 雑誌 magazine.resources :subscriptions # 購読 magazine.resources :numbers do |number| # ナンバー number.resources :articles, :new => { :draft => :post # 原稿登録 }, :member => { :correct => :post # 構成 } end end end
rake routesを実行すると、以下のようにヘルパーメソッド、HTTPメソッド、パス、paramsが出力されます。
パスに記述されているURLにそのHTTPメソッドでアクセスすると表にあるparams(と渡されたパラメータがマージされたもの)になります。
出力結果:
ヘルパーメソッド名 | HTTPメソッド | パス | params |
---|---|---|---|
POST | /sessions | {:controller=>"sessions", :action=>"create"} | |
POST | /sessions.:format | {:controller=>"sessions", :action=>"create"} | |
new_sessions | GET | /sessions/new | {:controller=>"sessions", :action=>"new"} |
formatted_new_sessions | GET | /sessions/new.:format | {:controller=>"sessions", :action=>"new"} |
edit_sessions | GET | /sessions/edit | {:controller=>"sessions", :action=>"edit"} |
formatted_edit_sessions | GET | /sessions/edit.:format | {:controller=>"sessions", :action=>"edit"} |
sessions | GET | /sessions | {:controller=>"sessions", :action=>"show"} |
formatted_sessions | GET | /sessions.:format | {:controller=>"sessions", :action=>"show"} |
PUT | /sessions | {:controller=>"sessions", :action=>"update"} | |
PUT | /sessions.:format | {:controller=>"sessions", :action=>"update"} | |
DELETE | /sessions | {:controller=>"sessions", :action=>"destroy"} | |
DELETE | /sessions.:format | {:controller=>"sessions", :action=>"destroy"} | |
magazines | GET | /magazines | {:controller=>"magazines", :action=>"index"} |
formatted_magazines | GET | /magazines.:format | {:controller=>"magazines", :action=>"index"} |
POST | /magazines | {:controller=>"magazines", :action=>"create"} | |
POST | /magazines.:format | {:controller=>"magazines", :action=>"create"} | |
new_magazine | GET | /magazines/new | {:controller=>"magazines", :action=>"new"} |
formatted_new_magazine | GET | /magazines/new.:format | {:controller=>"magazines", :action=>"new"} |
edit_magazine | GET | /magazines/:id/edit | {:controller=>"magazines", :action=>"edit"} |
formatted_edit_magazine | GET | /magazines/:id/edit.:format | {:controller=>"magazines", :action=>"edit"} |
magazine | GET | /magazines/:id | {:controller=>"magazines", :action=>"show"} |
formatted_magazine | GET | /magazines/:id.:format | {:controller=>"magazines", :action=>"show"} |
PUT | /magazines/:id | {:controller=>"magazines", :action=>"update"} | |
PUT | /magazines/:id.:format | {:controller=>"magazines", :action=>"update"} | |
DELETE | /magazines/:id | {:controller=>"magazines", :action=>"destroy"} | |
DELETE | /magazines/:id.:format | {:controller=>"magazines", :action=>"destroy"} | |
magazine_subscriptions | GET | /magazines/:magazine_id/subscriptions | {:controller=>"subscriptions", :action=>"index"} |
formatted_magazine_subscriptions | GET | /magazines/:magazine_id/subscriptions.:format | {:controller=>"subscriptions", :action=>"index"} |
POST | /magazines/:magazine_id/subscriptions | {:controller=>"subscriptions", :action=>"create"} | |
POST | /magazines/:magazine_id/subscriptions.:format | {:controller=>"subscriptions", :action=>"create"} | |
new_magazine_subscription | GET | /magazines/:magazine_id/subscriptions/new | {:controller=>"subscriptions", :action=>"new"} |
formatted_new_magazine_subscription | GET | /magazines/:magazine_id/subscriptions/new.:format | {:controller=>"subscriptions", :action=>"new"} |
edit_magazine_subscription | GET | /magazines/:magazine_id/subscriptions/:id/edit | {:controller=>"subscriptions", :action=>"edit"} |
formatted_edit_magazine_subscription | GET | /magazines/:magazine_id/subscriptions/:id/edit.:format | {:controller=>"subscriptions", :action=>"edit"} |
magazine_subscription | GET | /magazines/:magazine_id/subscriptions/:id | {:controller=>"subscriptions", :action=>"show"} |
formatted_magazine_subscription | GET | /magazines/:magazine_id/subscriptions/:id.:format | {:controller=>"subscriptions", :action=>"show"} |
PUT | /magazines/:magazine_id/subscriptions/:id | {:controller=>"subscriptions", :action=>"update"} | |
PUT | /magazines/:magazine_id/subscriptions/:id.:format | {:controller=>"subscriptions", :action=>"update"} | |
DELETE | /magazines/:magazine_id/subscriptions/:id | {:controller=>"subscriptions", :action=>"destroy"} | |
DELETE | /magazines/:magazine_id/subscriptions/:id.:format | {:controller=>"subscriptions", :action=>"destroy"} | |
magazine_numbers | GET | /magazines/:magazine_id/numbers | {:controller=>"numbers", :action=>"index"} |
formatted_magazine_numbers | GET | /magazines/:magazine_id/numbers.:format | {:controller=>"numbers", :action=>"index"} |
POST | /magazines/:magazine_id/numbers | {:controller=>"numbers", :action=>"create"} | |
POST | /magazines/:magazine_id/numbers.:format | {:controller=>"numbers", :action=>"create"} | |
new_magazine_number | GET | /magazines/:magazine_id/numbers/new | {:controller=>"numbers", :action=>"new"} |
formatted_new_magazine_number | GET | /magazines/:magazine_id/numbers/new.:format | {:controller=>"numbers", :action=>"new"} |
edit_magazine_number | GET | /magazines/:magazine_id/numbers/:id/edit | {:controller=>"numbers", :action=>"edit"} |
formatted_edit_magazine_number | GET | /magazines/:magazine_id/numbers/:id/edit.:format | {:controller=>"numbers", :action=>"edit"} |
magazine_number | GET | /magazines/:magazine_id/numbers/:id | {:controller=>"numbers", :action=>"show"} |
formatted_magazine_number | GET | /magazines/:magazine_id/numbers/:id.:format | {:controller=>"numbers", :action=>"show"} |
PUT | /magazines/:magazine_id/numbers/:id | {:controller=>"numbers", :action=>"update"} | |
PUT | /magazines/:magazine_id/numbers/:id.:format | {:controller=>"numbers", :action=>"update"} | |
DELETE | /magazines/:magazine_id/numbers/:id | {:controller=>"numbers", :action=>"destroy"} | |
DELETE | /magazines/:magazine_id/numbers/:id.:format | {:controller=>"numbers", :action=>"destroy"} | |
magazine_number_articles | GET | /magazines/:magazine_id/numbers/:number_id/articles | {:controller=>"articles", :action=>"index"} |
formatted_magazine_number_articles | GET | /magazines/:magazine_id/numbers/:number_id/articles.:format | {:controller=>"articles", :action=>"index"} |
POST | /magazines/:magazine_id/numbers/:number_id/articles | {:controller=>"articles", :action=>"create"} | |
POST | /magazines/:magazine_id/numbers/:number_id/articles.:format | {:controller=>"articles", :action=>"create"} | |
draft_new_magazine_number_article | POST | /magazines/:magazine_id/numbers/:number_id/articles/new/draft | {:controller=>"articles", :action=>"draft"} |
formatted_draft_new_magazine_number_article | POST | /magazines/:magazine_id/numbers/:number_id/articles/new/draft.:format | {:controller=>"articles", :action=>"draft"} |
new_magazine_number_article | GET | /magazines/:magazine_id/numbers/:number_id/articles/new | {:controller=>"articles", :action=>"new"} |
formatted_new_magazine_number_article | GET | /magazines/:magazine_id/numbers/:number_id/articles/new.:format | {:controller=>"articles", :action=>"new"} |
correct_magazine_number_article | POST | /magazines/:magazine_id/numbers/:number_id/articles/:id/correct | {:controller=>"articles", :action=>"correct"} |
formatted_correct_magazine_number_article | POST | /magazines/:magazine_id/numbers/:number_id/articles/:id/correct.:format | {:controller=>"articles", :action=>"correct"} |
edit_magazine_number_article | GET | /magazines/:magazine_id/numbers/:number_id/articles/:id/edit | {:controller=>"articles", :action=>"edit"} |
formatted_edit_magazine_number_article | GET | /magazines/:magazine_id/numbers/:number_id/articles/:id/edit.:format | {:controller=>"articles", :action=>"edit"} |
magazine_number_article | GET | /magazines/:magazine_id/numbers/:number_id/articles/:id | {:controller=>"articles", :action=>"show"} |
formatted_magazine_number_article | GET | /magazines/:magazine_id/numbers/:number_id/articles/:id.:format | {:controller=>"articles", :action=>"show"} |
PUT | /magazines/:magazine_id/numbers/:number_id/articles/:id | {:controller=>"articles", :action=>"update"} | |
PUT | /magazines/:magazine_id/numbers/:number_id/articles/:id.:format | {:controller=>"articles", :action=>"update"} | |
DELETE | /magazines/:magazine_id/numbers/:number_id/articles/:id | {:controller=>"articles", :action=>"destroy"} | |
DELETE | /magazines/:magazine_id/numbers/:number_id/articles/:id.:format | {:controller=>"articles", :action=>"destroy"} |
idでリソースが特定されるようなものについてのコントローラに着いては、map.resources(複数形)で、idで特定できないものについてはmap.resource(単数形)を使います。
これの何が便利なのかというと、基本的な動作を、index(GET), new(GET), create(POST), show(GET), edit(GET), update(PUT), destroy(DELETE)というCRUDに対応するようにある程度決めているところです。「ある程度」というのは、
number.resources :articles, :new => { :draft => :post # 原稿登録 }, :member => { :correct => :post # 構成 }
と記述されているように、基本的なCRUDに対応するアクション以外にも自由に追加できるためです。また、
map.resources :magazines do |magazine| # 雑誌 magazine.resources :subscriptions # 購読 end
という風に記述することで、ある特定の雑誌の購読についての動作であることがURL上でも表現でき、アクションではparamsに:magazine_idが設定されます。
これでアプリケーションの見通しがだいぶ違うはずです。このお約束を守ることが開発メンバー内で合意がとれていれば、大まかな画面遷移を決める人、画面の細かい動きを決める人、実装を行う人の間で誤解が生まれる可能性が少なくなります。URLをどんな感じにするのかについてもある程度決まっていることで、URLの設計に悩む時間も減ります。
という訳で、画面設計に関わる人はmap.resource(s)を押さえておくといいことあるはず、という話でした。