Rails Routes控制台测试
cd RubyOnRails/app/path cd script/console> rs = ActionController::Routing::Routes> puts rs.routesANY /:controller/service.wsdl/ {:action=>"wsdl"}ANY /:controller/:action/:id.:format/ {}ANY /:controller/:action/:id/ {}=>nil |
修改config/routes.rb文件,添加一行
map.connect 'modules/controller/:action/*other', :controller => 'modules/controller' |
回到console
> rs.reload> puts rs.routesANY /:controller/service.wsdl/ {:action=>"wsdl"}ANY /:controller/:action/:id.:format/ {}ANY /:controller/:action/:id/ {}ANY /modules/controller/:action/:other/ {:controller=>"modules/controller"}=>nil> rs.recognize_path '/modules/controller/test/2?x=1'=> {:action=>"test", :other=>["2?x=1"], :controller=>"modules/controller"}> rs.recognize_path '/test/action/1'=> {:action=>"action", :id=>"1", :controller=>"test"}> rs.add_route('/x/y/z', {:controller => 'test', :action => 'index', :id => 0})=> >puts rs.routesANY /:controller/service.wsdl/ {:action=>"wsdl"}ANY /:controller/:action/:id.:format/ {}ANY /:controller/:action/:id/ {}ANY /modules/controller/:action/:other/ {:controller=>"modules/controller"}ANY /x/y/z/ {:action=>"index", :id=>0, :controller=>"test"}=> nil> rs.draw do |map|?> map.connect '/blog/:id', :controller => 'blog', :action => 'list'> end=> [ActionController::Base, ActionView::Base]> puts rs.routesANY /blog/:id/ {:action=>"list", :controller=>"blog"}=> nil> rs.recognize_path '/blog/1'=> {:action=>"list", :id=>"1", :controller=>"blog"} |
这里发现原来的routes全部不见了,只有这个新建的routes了,因为draw方法内部实现为:
def draw clear! yield Mapper.new(self) named_routes.installend |
draw方法块里的map对象里method_missing方法就是用来实现具名路由named routes的。先看下源码如下:
def method_missing(route_name, *args, &proc) super unless args.length >= 1 && proc.nil? @set.add_named_route(route_name, *args)end |
上面对实例变量@set就是前面的rs对象,那么就看一下rs.add_named_route方法吧
> rs.clear!> rs.add_named_route('index', 'user/index', :controller => 'user', :action => 'index')puts rs.named_routes#=> nil> puts rs.routesANY /user/index/ {:action=>"index", :controller=>"user"}=> nil> puts rs.named_routes.routesindexANY /user/index/ {:action=>"index", :controller=>"user"}=> nil |
定义了具名路后就可以在controller/view中像url_for一样调用,只要在route name后面加上_url就可以,url_for在console里不能调试,可以用rs.generate(request)方法测试。
# In addition to providing url_for, named routes are also accessible after including UrlWriter.url_for(:controller => 'signup', action => 'index', :token => token)index_url(:id => 1)#=> http://localhost/user/index?id=1> rs.generate(:controller => 'test', :action => 'index', :id => 3)=> "/test/index/3" |
另外在map这个对象里有个方法root可以给根目录定义路径,用法如下:
> rs.draw do |map|?> map.root :controller => 'test', :action => 'list'> endArgumentError: Illegal route: the :controller must be specified! from /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/routing.rb:965:in `build' from /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/routing.rb:1172:in `add_route' from /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/routing.rb:1178:in `add_named_route' from /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/routing.rb:997:in `root_without_deprecation' from /usr/local/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/deprecation.rb:94:in `root' from (irb):60 from /usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/routing.rb:1139:in `draw' from (irb):59# Added deprecation notice for anyone who already added a named route called "root".# It'll be used as a shortcut for map.connect '' in Rails 2.0.# def root(*args, &proc)# super unless args.length >= 1 && proc.nil?# @set.add_named_route("root", *args)# end# deprecate :root => "(as the the label for a named route) will become a shortcut for map.connect '', so find another name" |
Rails2.0才会引进此方法,所以Rails建议用户不要使用此具名路由,如下:
> rs.draw do |map|?> map.root '', :controller => 'test', :action => 'list'> end=> [ActionController::Base, ActionView::Base]> puts rs.routesANY / {:action=>"list", :controller=>"test"}=> nil> puts rs.named_routes.routesrootANY / {:action=>"list", :controller=>"test"}=> nil |
这个写法其实就是做了个具名路由,而不是调用map.root方法,调用的是method_missing方法。