路由请求(定制URL-map.connect)

到现在为上,本书中我们已经不在烦恼,Rails 是如何映射一个请求如
store/add_to_cart/123 给一个特定的“控制器”和“动作”了。现在我们向深处看看。
rails 命令为一个应用程序生成最初的文件集。这些文件中的一个是config/routes.rb。
它为应用程序包含了“路由器”信息。如果你查看此文件的缺省内容,忽略注释的话,你会
看到下面这样。
ActionController::Routing::Routes.draw do |map|
map.connect ':controller/service.wsdl', :action => 'wsdl'
map.connect ':controller/:action/:id'
end
“路由器”组件绘制了一个映射,它可让Rails 将外部的URL 连接到应用程序内部。每
个map.connect 声明都指出一个外部URL 的连接和内部程序的代码。让我们看看第二个
map.connect 行。字符串’:controller/:action/:id’的行为像个模式,匹配URL 请求的路
径部分。在这个例子中,模式将匹配任何路径内包含这三个组件的URL。(实际上不是这样的,
但我们可以节省此解释的时间。)第一个组件被赋值给参数:controller,第二个组件给参
数:action,第三个给:id。将store/add_to_cart/123 URL 交给这个模式,你最终将得到些
参数。
@params = { :controller => 'store', :action => 'add_to_cart', :id =>
123 }
基于这些,Rails 将调用store controller 内的add_to_cart()方法。:id 参数将有123
这个值。
被map.connect 接受模式即简单又强大。
1、组件由反斜线字符分隔。模式内的每个组件匹配一个或多个URL 内的组成部分。在模
式内的组件按次序匹配URL。
2、一个模式有:name 这样的格式,用来设置参数的名字为URL 内相应位置的任何值。
3、模式也可以有*name 这样的格式,它接受引入的URL 的所有余下部分。有这种类型名
字的参数将引用一个包含它们的值的数组。因为它吞掉了URL 的所有余下部分,*name 必须
出现在模式的尾部。(译注:即是最后一个。)
4、一个模式内的任何部分都明确地匹配URL 内相应的位置。例如,一个包含
store/:controller/buy/:id 的模式将映射URL 路径内内前面的文本和第三个部分的文本。
map.connect 接受下面额外的参数:
1、:defaults => { :name => "value", ...} 为模式内指定名字的参数设置缺省值。模
式内尾部组件的缺省值会在引入的URL 中被省略,并且它们的缺省值会在设置参数时被使用。
带有缺省值nil 的参数若没有出现在URL 中,则它们会被添加到参数哈希表中。如果没有指
定缺省值,则route 将自动地使用缺省值。
defaults => { :action => "index", :id => nil }
2、:requirements => { :name =>/regexp/, ...} 指定给定的组件,如果组件在URL 中
出现的话,必须匹配指定的正则表达式,以便于映射整个匹配。换句话说,如果任何组件都
不匹配,这个映射将不会被使用。
3、:name => value 设置缺省值给组件:name。不像使用:defaults 设置的值,此名字不
需出现在模式本身内。这允许你添加任意的参数值给引入的请求。典型地这个值将是一个字
符串或者nil。
4、:name => /regexp/ 等价于使用:requirements 在:name 的值上设置约束。
还有一个规则:“路由器”会试着依次按routes.rb 内的每个规则来匹配一个引入的URL。
第一个成功的匹配会被使用。如果没有匹配成的话,引发一个错误。
让我们看此例子。Rails 缺省的route 定义包括下面规范。
ActionController::Routing::Routes.draw do |map|
map.connect ":controller/:action/:id"
end
下面列表显示一些请求路径和由这个“路由器”定义抽取的参数。记住那个“路由器”
设置index 的一个缺省“动作”,除非覆写它。
URL> store
@params = {:controller=>"store", :action=>"index"}
URL> store/list
@params = {:controller=>"store", :action=>"list"}
URL> store/display/123
@params = {:controller=>"store", :action=>"display", :id=>"123"}
现在让我们看个更复杂的例子。在你的博客应用程序中,你的所有URL 以单词blog 开头。
如果没有额外参数给出,则显示索引页。如果URL 如blog/show/nnn,你将显示nnn 文章。
如果URL 包含一个日期(它可能是年,年/月,或年/月/日),你将显示那个日期的文章。否则编辑文章或者是管理博客。最后,如果你接受到个未知的URL 模式,你将用于特定的“动作”来处理它。
下面“路由器”包含了每个单独的情况。
ActionController::Routing::Routes.draw do |map|

# Straight 'http://my.app/blog/' displays the index
map.connect "blog/",:controller => "blog",:action => "index"

# Return articles for a year, year/month, or year/month/day
map.connect "blog/:year/:month/:day",:controller => "blog",
:action => "show_date",
:requirements => { :year => /(19|20)dd/,:month => /[01]?d/,
:day => /[0-3]?d/},
:day => nil,
:month => nil

# Show an article identified by an id
map.connect "blog/show/:id",
:controller => "blog",
:action => "show",
:id => /d+/

# Regular Rails routing for admin stuff
map.connect "blog/:controller/:action/:id"

# Catch-all so we can gracefully handle badly-formed requests
map.connect "*anything",:controller => "blog",:action => "unknown_request"
end

还有几个事情要注意一下。首先,我们并没有强制日期匹配规则中年,月,日的值。除
了这一点,规则还匹配正规URL,controller/action/id。其次,还要注意我们是如何在列表的尾部使用万能规则(“*anything”)的。因为这个规则匹配所有请求,把它放到前边的话,后面规则就不会起作用。

我们可以看看这些规则是如何处理一些URL 请求的。
URL> blog
@params = {:controller=>"blog", :action=>"index"}
URL> blog/show/123
@params = {:controller=>"blog", :action=>"show", :id=>"123"}
URL> blog/2004
@params = {:controller=>"blog", :action=>"show_date", :year=>"2004"}
URL> blog/2004/12
@params = {:controller=>"blog", :action=>"show_date", :month=>"12",
:year=>"2004"}
URL> blog/2004/12/25
@params = {:controller=>"blog", :action=>"show_date", :day=>"25",
:month=>"12", :year=>"2004"}
URL> blog/article/edit/123
@params = {:controller=>"article", :action=>"edit", :id=>"123"}
URL> blog/article/show_stats
@params = {:controller=>"article", :action=>"show_stats"}
URL> blog/wibble
@params = {:controller=>"wibble", :action=>"index"}
URL> junk
@params = {:anything=>["junk"], :controller=>"blog",
:action=>"unknown_request"}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值