我在视图中有这个RoR片段:
<%= link_to_unless(@posts_pages[:previous].nil?,
"Previous",
blog_with_page_path(:page_num => @posts_pages[:previous])) %>
这里blog_with_page是一个命名路线。如果@posts_pages[:previous].nil?
为false
(正如预期的那样)并且链接生成正确,则代码段有效。但是,当@posts_pages[:previous].nil?
为true
时,我收到错误,告诉我无法使用"Previous"
生成路由,而不是简单地返回:page_num=>nil
字符串。这是预期的行为吗?如果满足条件,则不应评估路径代码,是否应该进行评估?
这是完整的错误:
blog_with_page_url failed to generate from {:page_num=>nil, :action=>"show", :controller=>"pages"}, expected: {:action=>"show", :controller=>"pages"}, diff: {:page_num=>nil}
我一直在查看link_to_unless
代码,我不明白为什么我会收到错误,因为它应该只返回名称:
# File actionpack/lib/action_view/helpers/url_helper.rb, line 394
def link_to_unless(condition, name, options = {}, html_options = {}, &block)
if condition
if block_given?
block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block)
else
name
end
else
link_to(name, options, html_options)
end
end
我正在使用Rails 2.3.11和Ruby 1.8.7
干杯!
答案 0 :(得分:2)
由于Ruby不是一种惰性语言,因此blog_with_page_path(:page_num => @posts_pages[:previous])
会在您调用它时立即对其进行评估,无论该值是否被link_to_unless
使用。
答案 1 :(得分:1)
鉴于解决您问题的其他各种答案,为什么不尝试这个作为您的解决方案:
link_to( "Previous", blog_with_page_path(:page_num => @posts_pages[:previous]) ) unless @posts_pages[:previous].nil?
这将首先评估“除非”条件,在@post_pages[:previous]
为零时免除伪造link_to。
- 编辑 -
正如评论中指出的那样,既然你需要字符串,那么最简单的方法就是三元组:
@posts_pages[:previous].nil? ? "Previous" : link_to( "Previous", blog_with_page_path(:page_num => @posts_pages[:previous]) )
答案 2 :(得分:0)
它看起来像一个bug。此代码不是“懒惰”,因此它执行所有语句。所以你可以采取三种方式:
if .. else
喜欢这个
<%= link_to_unless(@posts_pages[:previous].nil?,
"Previous",
blog_with_page_path(:page_num => @posts_pages[:previous] || 0)) %>
您可以设置任何数字,而不是0
,而不会设置
答案 3 :(得分:0)
函数参数总是在函数运行之前计算,无论是否需要它们:
ree-1.8.7-2011.03 :005 > def print_unless(condition, thing_to_print)
ree-1.8.7-2011.03 :006?> puts "I started executing"
ree-1.8.7-2011.03 :007?> puts thing_to_print unless condition
ree-1.8.7-2011.03 :008?> end
=> nil
ree-1.8.7-2011.03 :009 > print_unless(true, 1/0)
ZeroDivisionError: divided by 0
from (irb):9:in `/'
from (irb):9
from :0