在 RESTful 與 Rails 中介紹過Rails對REST的基本支援,除了基本的resources設定之外,你還可以作一些進階設定,例如單個資源的URL定義,像是想對messages/:id/preview這樣的路由作定義,可以如下:
resources :messages do
member do
get 'preview'
end
end
如此一來,就可以使用對像messages/1/preview作GET請求,請求會由messages_controller.rb中定義的preview動作處理,有preview_message_path與preview_message_url輔助方法可以使用。member中也可以使用match設定。例如:
resources :messages do
member do
match 'preview', :to => 'messages#preview', :via => 'post'
end
end
也可以如下定義:
resources :messages do
get 'preview', :on => :member
end
也可以使用rake routes來得知路由對應:
preview_message GET /messages/:id/preview(.:format) {:action=>"preview", :controller=>"messages"}
messages GET /messages(.:format) {:action=>"index", :controller=>"messages"}
POST /messages(.:format) {:action=>"create", :controller=>"messages"}
new_message GET /messages/new(.:format) {:action=>"new", :controller=>"messages"}
edit_message GET /messages/:id/edit(.:format) {:action=>"edit", :controller=>"messages"}
message GET /messages/:id(.:format) {:action=>"show", :controller=>"messages"}
PUT /messages/:id(.:format) {:action=>"update", :controller=>"messages"}
DELETE /messages/:id(.:format) {:action=>"destroy", :controller=>"messages"}
如果想對多個資源的URL作定義,例如想對messages/search的GET作定義,則可以如下:
resources :messages do
collection do
get 'search'
end
end
如此也會產生search_messages_path與search_messages_url可以使用。可以使用rake routes來得知路由對應:
search_messages GET /messages/search(.:format) {:action=>"search", :controller=>"messages"}
messages GET /messages(.:format) {:action=>"index", :controller=>"messages"}
POST /messages(.:format) {:action=>"create", :controller=>"messages"}
new_message GET /messages/new(.:format) {:action=>"new", :controller=>"messages"}
edit_message GET /messages/:id/edit(.:format) {:action=>"edit", :controller=>"messages"}
message GET /messages/:id(.:format) {:action=>"show", :controller=>"messages"}
PUT /messages/:id(.:format) {:action=>"update", :controller=>"messages"}
DELETE /messages/:id(.:format) {:action=>"destroy", :controller=>"messages"}
資源有時必須巢狀顯示,例如messages/1的回應,也許可以用messages/1/replies來表示(訊息與回應為 一對多 的情況),這時可以如下設定:
resources :messages do
resources :replies
end
使用rake routes來得知路由對應:
message_replies GET /messages/:message_id/replies(.:format) {:action=>"index", :controller=>"replies"}
POST /messages/:message_id/replies(.:format) {:action=>"create", :controller=>"replies"}
new_message_reply GET /messages/:message_id/replies/new(.:format) {:action=>"new", :controller=>"replies"}
edit_message_reply GET /messages/:message_id/replies/:id/edit(.:format) {:action=>"edit", :controller=>"replies"}
message_reply GET /messages/:message_id/replies/:id(.:format) {:action=>"show", :controller=>"replies"}
PUT /messages/:message_id/replies/:id(.:format) {:action=>"update", :controller=>"replies"}
DELETE /messages/:message_id/replies/:id(.:format) {:action=>"destroy", :controller=>"replies"}
messages GET /messages(.:format) {:action=>"index", :controller=>"messages"}
POST /messages(.:format) {:action=>"create", :controller=>"messages"}
new_message GET /messages/new(.:format) {:action=>"new", :controller=>"messages"}
edit_message GET /messages/:id/edit(.:format) {:action=>"edit", :controller=>"messages"}
message GET /messages/:id(.:format) {:action=>"show", :controller=>"messages"}
PUT /messages/:id(.:format) {:action=>"update", :controller=>"messages"}
DELETE /messages/:id(.:format) {:action=>"destroy", :controller=>"messages"}
也就是說實際上處理的動作,必須在replies_controller.rb中定義RepliesController,並於其中定義對應的動作,像先前member與collection定義時,若有不瞭解URL對應與輔助方法時,也可以使用rake routes來得知。
resources用來定義複數資源,如果要定義單數資源,可以使用resource(沒有s),例如若訊息與最佳解答可以如下定義(為 一對一 的情況):
resources :messages do
resource :answer # 單數
end
使用rake routes來得知路由對應:
message_answer POST /messages/:message_id/answer(.:format) {:action=>"create", :controller=>"answers"}
new_message_answer GET /messages/:message_id/answer/new(.:format) {:action=>"new", :controller=>"answers"}
edit_message_answer GET /messages/:message_id/answer/edit(.:format) {:action=>"edit", :controller=>"answers"}
GET /messages/:message_id/answer(.:format) {:action=>"show", :controller=>"answers"}
PUT /messages/:message_id/answer(.:format) {:action=>"update", :controller=>"answers"}
DELETE /messages/:message_id/answer(.:format) {:action=>"destroy", :controller=>"answers"}
messages GET /messages(.:format) {:action=>"index", :controller=>"messages"}
POST /messages(.:format) {:action=>"create", :controller=>"messages"}
new_message GET /messages/new(.:format) {:action=>"new", :controller=>"messages"}
edit_message GET /messages/:id/edit(.:format) {:action=>"edit", :controller=>"messages"}
message GET /messages/:id(.:format) {:action=>"show", :controller=>"messages"}
PUT /messages/:id(.:format) {:action=>"update", :controller=>"messages"}
DELETE /messages/:id(.:format) {:action=>"destroy", :controller=>"messages"}
你可以為URL加上名稱空間。例如admin/messages/1、admin/messages/new這樣的URL,可以如下設定:
namespace :admin do
resources :messages
end
使用rake routes來看有哪些路由對應:
admin_messages GET /admin/messages(.:format) {:action=>"index", :controller=>"admin/messages"}
POST /admin/messages(.:format) {:action=>"create", :controller=>"admin/messages"}
new_admin_message GET /admin/messages/new(.:format) {:action=>"new", :controller=>"admin/messages"}
edit_admin_message GET /admin/messages/:id/edit(.:format) {:action=>"edit", :controller=>"admin/messages"}
admin_message GET /admin/messages/:id(.:format) {:action=>"show", :controller=>"admin/messages"}
PUT /admin/messages/:id(.:format) {:action=>"update", :controller=>"admin/messages"}
DELETE /admin/messages/:id(.:format) {:action=>"destroy", :controller=>"admin/messages"}