map.resourcesを試してみる
Userモデルと、index(一覧表示)、show(ひとつの表示)、new,create(新規作成)、edit,update(更新)、destroy(削除)のアクションを持つコントローラがあったとすると、config/routes.rbに
map.resources :users
と書くだけでカッコいいURIを自動で作ってくれます。その確認はrake routesコマンドでOK。
users GET /users {:action=>"index", :controller=>"users"}
formatted_users GET /users.:format {:action=>"index", :controller=>"users"}
POST /users {:action=>"create", :controller=>"users"}
POST /users.:format {:action=>"create", :controller=>"users"}
new_user GET /users/new {:action=>"new", :controller=>"users"}
formatted_new_user GET /users/new.:format {:action=>"new", :controller=>"users"}
edit_user GET /users/:id/edit {:action=>"edit", :controller=>"users"}
formatted_edit_user GET /users/:id/edit.:format {:action=>"edit", :controller=>"users"}
user GET /users/:id {:action=>"show", :controller=>"users"}
formatted_user GET /users/:id.:format {:action=>"show", :controller=>"users"}
PUT /users/:id {:action=>"update", :controller=>"users"}
PUT /users/:id.:format {:action=>"update", :controller=>"users"}
DELETE /users/:id {:action=>"destroy", :controller=>"users"}
DELETE /users/:id.:format {:action=>"destroy", :controller=>"users"}
左から、名前、メソッド、URI、実際のアクション、になります。/usersに対してGETメソッドでアクセスすると一覧表示、同じURIに対してPOSTメソッドでデータを送ると、新しいモデルオブジェクトが作成されます。/users/:idに対してGETメソッドでひとつのデータの表示、PUTメソッドで更新、DELETEメソッドで削除されます。RESTfulでカッコいい。
さらにUserモデルに1対多でひもつくCarモデルがあった場合、config/routes.rbに
map.resources :users, :has_many => :cars
と書いてやることで、
.....省略......
user_cars GET /users/:user_id/cars {:action=>"index", :controller=>"cars"}
formatted_user_cars GET /users/:user_id/cars.:format {:action=>"index", :controller=>"cars"}
POST /users/:user_id/cars {:action=>"create", :controller=>"cars"}
POST /users/:user_id/cars.:format {:action=>"create", :controller=>"cars"}
new_user_car GET /users/:user_id/cars/new {:action=>"new", :controller=>"cars"}
formatted_new_user_car GET /users/:user_id/cars/new.:format {:action=>"new", :controller=>"cars"}
edit_user_car GET /users/:user_id/cars/:id/edit {:action=>"edit", :controller=>"cars"}
formatted_edit_user_car GET /users/:user_id/cars/:id/edit.:format {:action=>"edit", :controller=>"cars"}
user_car GET /users/:user_id/cars/:id {:action=>"show", :controller=>"cars"}
formatted_user_car GET /users/:user_id/cars/:id.:format {:action=>"show", :controller=>"cars"}
PUT /users/:user_id/cars/:id {:action=>"update", :controller=>"cars"}
PUT /users/:user_id/cars/:id.:format {:action=>"update", :controller=>"cars"}
DELETE /users/:user_id/cars/:id {:action=>"destroy", :controller=>"cars"}
DELETE /users/:user_id/cars/:id.:format {:action=>"destroy", :controller=>"cars"}
といったURIが作られます。
名前つきrouteは、モデルのインスタンスを指定してあげるだけ。
@user = User.find(1)
user_url(@user) #=> http://localhost:3000/users/1
user_path(@user) #=> /users/1
@car = @user.find(2)
user_car_path(@user, @car) #=> /users/1/cars/2
さらにすごいのは、link_toとかredirect_toとかform_for
@user = User.find(1)
link_to(h(@user.name), @user) #=> link_to h(@user.name), :controller => "users", :action => "show", :id => 1
redirect_to(@user) #=> redirect_to "/users/1"
form_for(@user) #=> action="/users/1" method="PUT"
@user = User.new
redirect_to(@user) #=> redirect_to "/users"
form_for(@user) #=> action="/users" method="POST"
オブジェクトの状態を見て、空のときとそうでないときとで、URIが変化するのだ。これはすごい。
ちなみに、carsのようなhas_many状態のrouteでは、単純にオブジエクトを指定するのではなくて名前つきroutesを使用したほうがよさそう。