url_for

生成URL
“路由器”接受一个URL,并解码它到参数集中,这些参数再由Rails 分派给适当的“控
制器”和“动作”(也按此方式潜在地设置额外的参数)。但是这只是故事的一半。我们的应
用程序也需要创建能引用其自身的URL。例如,每次显示一个表单时,表单需要被连接回一
个“控制器”和“动作”。但应用程序的代码不必知道URL 格式的编码信息;它们被看成是
被调的参数,“路由器”用这些参数完成工作。
我们可以硬编码所有的URL 到应用程序中,但稍微懂些请求格式的人都会伤害到我们的
程序。这违反了DRY 原则;当修改应用程序的位置或URL 格式时,我们必须修改所有这些字
符串。
幸运地是我们不用担心,Rails 通过使用url_for ()方法(还有很多高级用法)也抽象了
URL 的生成。要演示这个,让我们回到一个简单映射中。
map.connect ":controller/:action/:id"
url_for ()方法通过将它的参数传递给一个映射来生成URL。在可以在“控制器”和“视
图”中工作。让我们试试。
url_for ()方法通过将它的参数传递给一个映射来生成URL。在可以在“控制器”和“视图”
中工作。让我们试试。
@link = url_for :controller => "store", :action => "display", :id =>
123
这个代码将把@link 设置成像这样
http://pragprog.com/store/display/123
url_for ()方法接受我们的参数并映射它们到一个与我们自己的“路由器”兼容的请求中。
如果用户选择了有些连接的URL,它将调用我们应用程序希望的动作。
经过重载后的url_for ()会更聪明。它知道有关的缺省参数并生成你希望的最小限度的
URL。让我们看一些例子。
# 没有action 或者id, 则重载版本使用缺省值。
url_for (:controller => "store")
#=> http://pragprog.com/store
# 如果action 被丢失,则重载版本会在URL 中插入缺省值—index。
url_for (:controller => "store", :id => 123)
#=> http://pragprog.com/store/index/123
# id 是可选的。
url_for (:controller => "store", :action => "list")
#=> http://pragprog.com/store/list
# 一个完整的请求。
url_for (:controller => "store", :action => "list", :id => 123)
#=> http://pragprog.com/store/list/123
# 额外的参数被添加到URL 的尾部。
url_for (:controller => "store", :action => "list",:id => 123, :extra
=> "wibble")
#=> http://rubygarden.org/store/list/123?extra=wibble
缺省机制使用从当前请求获得的值。如果:controller 参数被忽略的话,这是大多数填
充当前“控制器”的名字的用法。假设下面例子在处理传递给store “控制器”的请求时运
行。注意,它如何填充URL 内的“控制器”名字。
url_for (:action => "status")
#=> http://pragprog.com/store/status
URL 生成工作以可用于更复杂的“路由器”。例如,我们博客的“路由器”包含下面映
射。
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, # optional
:month => nil # optional
map.connect "blog/show/:id",
:controller => "blog",
:action => "show",
:id => /d+/ # must be numeric
map.connect "blog/:controller/:action/:id"
假设引入请求是http://pragprog.com/blog/2005/4/15。这个请求会被第一个规则映射
给Blog “控制器”的show_date 动作。让我们看看在这些情况下,会产生什么样的url_for ()
调用。
如果我们为不同的天要求一个URL,映射调用将接受来自请求的值做缺省值,只是day
参数改变了。
url_for (:day => "25")
#=> http://pragprog.com/blog/2005/4/25
现在让我们看看,如果我们给出年会发生什么情况。
url_for (:year => "2004")
#=> http://pragprog.com/blog/2004
太灵巧了。映射代码设想URL 被表示成一个值的层次。[在web 上这很正常,静态的内容
被存储在文件夹(目录)内,它们本身也可以是文件夹,等等。]一旦我们在这个层次的一个级
别上修改一些东西的缺省值,它会停止给较低级别提供缺省值。最合理的解释是:低层的参
数事实上只能在高层中使用,所以修改的缺省值在低层中无效。在这个例子中通过覆写年,
我们含蓄地告诉映射代码,我们不需要月和天。
也要注意映射代码会为提交的URL 尽可能地选择第一条规则。让我们看看,如果我们给
它不能由第一条规则—基于日期的规则,匹配的值,会发生什么事情。
url_for (:action => "edit", :id => 123)
#=> http://pragprog.com/blog/blog/edit/123
这儿,第一个blog 是固定文本,第二个blog 是“控制器”的名字,edit 是“动作”名
字—映射代码应用第三个规则。如果我们指定“动作”为show,则映射代码使用第二个规则。
url_for (:action => "show", :id => 123)
#=> http://pragprog.com/blog/show/123
大多数时候映射代码会完成你想要的工作。但是,它有时候也太聪明了。如果你想生成
2005 年的URL。你可以写
url_for (:year => "2005")
当你看到映射代码解释的URL 也包含月和天时,你会大吃一惊。
#=> http://pragprog.com/blog/2005/4/15
你提供的年的值也同样被用在当前请求中。因为这个参数没有被修改,映射为URL 的余
下部分使用了月和天的缺省值。要避免这样,可设置月的参数为nil。
url_for (:year => "2005", :month => nil)
#=> http://pragprog.com/blog/2005
通常,如果你想生成一个特定的URL,最好的办法是设置未被使用的第一个参数为nil;
这样做可避免使用URL 留下的参数。
有时候你希望做相反的事情,修改层次中高层参数的值,并强迫“路由器”代码继续使
用低层中的值。在我们例子中,这就像是在URL 指定了一个不同的年,并在它的后面添加现
有的月和日的缺省值。要做到这点,我们可以欺骗“路由器”代码—我们使
用:overwrite_params 选项来告诉它,原有请求的参数包含我们想使用的新的年。因为它认
为年没有被修改,它继续使用余下的缺省值。
url_for (:year => "2002")
#=> http://pragprog.com/blog/2002
url_for (:overwrite_params => {:year => "2002"})
#=> http://pragprog.com/blog/2002/4/15
一个映射有个必须条件,如
map.connect "blog/:year/:month/:day",
:controller => "blog",
:action => "show_date",
:requirements => { :year => /(19|20)dd/,
:month => /[01]d/,
:day => /[0-3]d/},
注意:day 参数必须匹配/[0-3]d/;它必须有两个数字长。这意味着当创建一个URL 时,
如果你传递的Fixnum 值小于10,这个规则将不会起作用。
url_for (:year => 2005, :month => 12, :day =>
因为数字8 被转换为字符串”8”,而那个字符没两个数字长,映射就不会被激活。可以
是对relax 规则(在请求中使用[0-3]?d 来要求前导的零)进行修改,或者是确保你传递两个数字。
url_for (:year=>year,
:month=>sprintf("%02d", month),
:day=>sprintf("%02d", day))


在182 页我们说过,“控制器”应该被分组到模块中,并且引入的URL 使用类似路径的
约定来确定这些“控制器”。http://my.app/admin/book/edit/123 的URL 将调用Admin 模块内Book“控制器”的edit“动作”。
这个映射也影响URL 的生成。
1、如果你没有指定一个:controller 参数给url_for (),它使用当前的“控制器”。
2、如果你传递一个以a/开头的“控制器”的名字,那么那个名字是绝对的。
3、所有其它的“控制器”名字则相对于请求的“控制器”的模块。
要说明这一点,让我们假设有个请求是
http://my.app/admin/book/edit/123
url_for (:action => "edit", :id => 123)
#=> http://my.app/admin/book/edit/123
url_for (:controller => "catalog", :action => "show", :id => 123)
#=> http://my.app/admin/catalog/show/123
url_for (:controller => "/store", :action => "purchase", :id => 123)
#=> http://my.app/store/purchase/123
url_for (:controller => "/archive/book", :action => "record", :id =>
123)
#=> http://my.app/archive/book/record/12
(如果在controller控制器内容的前面加上'/'号,则对应部分的内容会以绝对路径的形式显示在url地址中

Rails 用它自己的方式为怎么让URL 有个好名字而提供了足够的灵活性。事实上,它支
持的足够深,以至于你可以混合你的“模型”类。“模型”与“视图”之间的这种交互似乎
违背了MVC,但对我们却很有好处。
让我们假设你希望你的URL 看起来这样:/clients/pragprog/agilweb,以便你使用
/clients/:client/:project 做为“路由器”。你可以这样生成URL。
url_for :controller => "clients",
:client => @company.short_name,
:project => @project.code_name
这很好,但是它意味着我们要给一个公司生成一个URL 组件,我们需要记住调用
short_name(),并且每次我们都包括一个project 在URL 中,我们必须调用code_name()。
如果一个对象实现了方法to_param(),则方法的返回值将在向URL 提供值是被使用(不
是to_s())。通过在Company 和Project 两者中实现适当的to_param()方法,我们可以对连
接的生成简化为
url_for :controller => "clients",
:client => @company,
:project => @project
Doesn’t that just make you feel all warm and fuzzy?
----------------------------------------------------------
现在我们已经看到映射是如何被用于生成URL 的,我们可以全面地查看url_for ()方法。
url_for 创建引用这个应用程序的一个URL。
url_for (option => value, ...)
在这个应用程序中创建个引用了一个“控制器”的URL。哈希表选项支持参数的名字和
它们用于填充URL(基于一个映射)的值。参数值必须匹配任何由使用的映射强加的约束。在
选项列表内的某些参数的名字:余下部分,被保留并且用于填充URL 的非路径部分。如果你
使用一个“活动记录”的“模型”对象做为url_for ()(或者是任何相关的方法)内的一个参
数,则那个对象的数据库id 将会被使用。下面代码片断内的两个重定向调用有同样的效果。
user = User.find_by_name("dave thomas")
redirect_to(:action => 'delete', :id => user.id)
# can be written as
redirect_to(:action => 'delete', :id => user)
url_for ( ) 也接受单个字符串或符号做为一个参数。这一般在Rails 内部使用。
在下面表内通过在你的“控制器”内实现方法default_url_options(),你就可以覆写用于参数
缺省值。这应该返回一个参数的哈希表,此表被传递给url_for ()。
选项:
1、:anchor 字符串,附加给URL 的一个锚点名字。Rails 自动预定为#character。
2、:host 字符串,设置URL 内主机的名字和端口。使用字符串如store.pragprog.com 或
者helper.pragprog.com:8080,缺省是传给主机。
3、:only_path boolean ,只生成URL 的路径部分;协议,主机名字,和端口被忽略。
4、:protocol 字符串, 设置URL 的协议部分。使用一个字符串如”https://”。缺省
使用引入请求的协议。
5、:trailing_slash boolean ,给被生成的URL 附加一个反斜线。[如果你也使用页或
动作缓存的话,对:trailing_slash 应小心使用。额外的反斜线会弄乱缓存算法。]

 

From:

http://jbf034.javaeye.com/blog/221123

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值