2010年6月1日 星期二

rails2.3 routes 新語法

rails2.3 routes筆記 - 逆水行舟

參考鏈接:http://guides.rubyonrails.org/routing.html

多个简单的RESTful的路由可以这样定义:
Ruby代码
收藏代码

map.resources :photos, :books, :videos


以上代码相当于:
Ruby代码
收藏代码

map.resources :photos
map.resources :books
map.resources :videos



单数形式的Resource:
map.resource将生成6个路由规则,与复数形式的resources所不同的是,复数形式多了一个index的action对应的规则,单数形式不需要index,只需要一个show即可。生成的url稍微有所不同,不过和复数形式的resources一样,这些url不用记,有规律,很容易想到该怎么写。

可以通过:controller选项修改RESTful路由默认的controller,比如:
Ruby代码
收藏代码

map.resources :photos, :controller => "images"


本来pohtos的controller是PhotosController,这里变成了ImagesController。

=begin
guides中有这么个用法:
引用
You can also specify a controller namespace with the :namespace option instead of a path:
Ruby代码
收藏代码

map.resources :adminphotos, :namespace => "admin", :controller => "photos"


This can be especially useful when combined with with_options to map multiple namespaced routes together:
Ruby代码
收藏代码

map.with_options(:namespace => "admin") do |admin|
admin.resources :photos, :videos
end


That would give you routing for admin/photos and admin/videos controllers.

可我试了,好像并不是这么回事。
我仿着写了一段:
Ruby代码
收藏代码

map.with_options(:namespace=>'admin') do |admin|
admin.resources :books, :box
end


可我访问/admin/books时Rails却报告No route matches。再试了一下访问/books,却有结果了,结果是:NameError in AdminbooksController#index ——它在原来的BooksController前边加了一个Admin并且把B小写了……
翻了Rails的api也没见着这个:namespace的用法,实在搞不明白。
=end

:singular选项

如果rails不认识某个单词的单数形式,可以通过:singular来设置:
比如有如下routes代码:
Ruby代码
收藏代码

map.resources :teeth


这时候如果在页面上或者Controller里使用tooth_url,Rails会不认识这个tooth——teeth的单数形式,这种情况下就可以加上:singular => "tooth":
Ruby代码
收藏代码

map.resources :teeth, :singular => "tooth"



:as选项
用于修改路由能够识别的url,例如有如下routes代码:
Ruby代码
收藏代码

map.resources :photos, :as => "images"


这时访问/images会被Rails识别,并且调用PhotosController的index方法。但/photos这个URL将不再被Rails识别。

:conditions选项
用于限制能够被识别的请求的HTTP动作,一般不推荐用于RESTful的路由规则中。但可以在map.connect等方法中使用。
用法:
Ruby代码
收藏代码

map.connect 'photo/:id', :controller => 'photos', :action => 'show', :conditions => { :method => :get }



:requirements选项
用于限制url参数的格式,比如:
Ruby代码
收藏代码

map.resources :photos, :requirements => {:id => /[A-Z][A-Z][0-9]+/}


这样,/photos/1将不再被识别,/photos/AB2会被识别。

:path_name选项
用于给自动生成的URL中的'new'和'edit'重命名,但并不改变这两个action的名称,用法:
Ruby代码
收藏代码

map.resources :photos, :path_names => { :new => 'make', :edit => 'change' }


以上,/photos/make仍然调用controller里的new方法。
如果你希望整个rails项目中都使用上面的url,而不是默认的new、edit,可以在enviroment.rb中这样配置:
Ruby代码
收藏代码

config.action_controller.resources_path_names = { :new => 'make', :edit => 'change' }



:only、:except选项
引用
By default, Rails creates routes for all seven of the default actions (index, show, new, create, edit, update, and destroy) for every RESTful route in your application. You can use the : only and :except options to fine-tune this behavior. The : only option specifies that only certain routes should be generated:
Ruby代码
收藏代码

map.resources :photos, :only => [:index, :show]



With this declaration, a GET request to /photos would succeed, but a POST request to /photos (which would ordinarily be routed to the create action) will fail.

The :except option specifies a route or list of routes that should not be generated:
Ruby代码
收藏代码

map.resources :photos, :except => :destroy



In this case, all of the normal routes except the route for destroy (a DELETE request to /photos/id) will be generated.


引用
If your application has many RESTful routes, usingnly and :except to generate only the routes that you actually need can cut down on memory use and speed up the routing process.


:has_one、:has_many 嵌套资源的一种简洁写法:
Ruby代码
收藏代码

map.resources :photos, :has_one => :photographer, :has_many => [:publications, :versions]



2.x的rails开始支持namespace:
Ruby代码
收藏代码

map.namespace(:admin) do |admin|
admin.resources :photos, :has_many => { :tags, :ratings}
end


/admin/photos 将调用Admin::PhotosController的index方法。

:member :collection选项
Ruby代码
收藏代码

map.resources :photos, :member => { :preview => :get }
map.resources :photos, :member => { :prepare => [:get, :post] }
map.resources :photos, :collection => { :search => :get }



GET /photos/1/preview
POST /photos/1/prepare
GET /photos/search

引用
A Note of Caution

If you find yourself adding many extra actions to a RESTful route, it’s time to stop and ask yourself whether you’re disguising the presence of another resource that would be better split off on its own. When the :member and :collection hashes become a dumping-ground, RESTful routes lose the advantage of easy readability that is one of their strongest points.


后面是比较常用的connect的用法,比较熟悉,就不记了。倒是有个with_options第一次见到:
Ruby代码
收藏代码

map.with_options :controller => 'photo' do |photo|
photo.list '', :action => 'index'
photo.delete ':id/delete', :action => 'delete'
photo.edit ':id/edit', :action => 'edit'
end


用于批量设置一组具有某相同选项的路由规则。

rake routes 可以在控制台按顺序输出所有的路由规则。