Why does Rails create the path to the current page in the href
atribute of the anchor element instead of raising an exception if I pass to the link_to
meth开发者_高级运维od an instance variable which isn't associated with any resource (and equals nil
)?
Here's an example:
Routes
# app/config/routes.rb
Example::Application.routes.draw do
resource :example
end
HAML
-# app/views/examples/show.html.haml
%div
= link_to 'Non-existent resource', @ne_resource
HTML
<!-- http://localhost/example -->
<div>
<a href="/example">Non-existent resource</a>
Thanks.
Debian GNU/Linux 6.0.1;
Ruby 1.9.2;
Ruby on Rails 3.0.6.
If you take a look at the link_to method it links to the url using the url_for method.
def link_to(*args, &block)
if block_given?
options = args.first || {}
html_options = args.second
link_to(capture(&block), options, html_options)
else
name = args[0]
options = args[1] || {}
html_options = args[2]
html_options = convert_options_to_data_attributes(options, html_options)
url = url_for(options) #THIS GETS CALLED
href = html_options['href']
tag_options = tag_options(html_options)
href_attr = "href=\"#{html_escape(url)}\"" unless href
"<a #{href_attr}#{tag_options}>#{html_escape(name || url)}</a>".html_safe
end
end
URL for
def url_for(options = {})
options ||= {}
url = case options
when String
options
when Hash #THIS CASE IS TRUE
options = options.symbolize_keys.reverse_merge!(:only_path => options[:host].nil?)
super
when :back
controller.request.env["HTTP_REFERER"] || 'javascript:history.back()'
else
polymorphic_path(options)
end
url
end
From the above, you can see that url_for is valid without options or with a nilClass, it is not designed to raise an exception. If you want errors when using link_to, then make sure to use the dynamic "path" helper methods, in the above case, new_example_path.
I asked DHH (the creator of Rails) a closely related question about link_to's behavior when passed nil, nil
arguments. I was hoping it would just not render an tag at all, instead of making me check for nils before calling it. He graciously replied:
https://twitter.com/dhh/status/198487578352156672
The essence of this answer applies to your question. It needs to do something when it is handed a nil
. Gazler points out what's technically happening, but DHH's response shows a bit of the higher level "why?" The url_for
method is fine with taking a nil argument, with the current page a sensible default.
精彩评论