Ruby on Rails. link_to не вызывает исключения

#ruby-on-rails #helpers

#ruby-on-rails #помощник

Вопрос:

Почему Rails создает путь к текущей странице в href атрибуте элемента привязки вместо того, чтобы вызывать исключение, если я передаю link_to методу переменную экземпляра, которая не связана ни с каким ресурсом (и равна nil )?

Вот пример:

Маршруты

 # 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>
  

Спасибо.

Debian GNU / Linux 6.0.1;

Ruby 1.9.2;

Ruby on Rails 3.0.6.

Ответ №1:

Если вы посмотрите на метод link_to, он ссылается на URL с использованием метода url_for.

   def link_to(*args, amp;block)
    if block_given?
      options      = args.first || {}
      html_options = args.second
      link_to(capture(amp;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 для

   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
  

Из приведенного выше вы можете видеть, что url_for допустим без параметров или с NilClass , он не предназначен для создания исключения. Если вы хотите, чтобы при использовании link_to возникали ошибки, то обязательно используйте динамические вспомогательные методы «path», в приведенном выше случае new_example_path .

Ответ №2:

Я задал DHH (создателю Rails) тесно связанный вопрос о поведении link_to при передаче nil, nil аргументов. Я надеялся, что это просто не будет отображать тег вообще, вместо того, чтобы заставлять меня проверять наличие нулей перед его вызовом. Он любезно ответил:

https://twitter.com/dhh/status/198487578352156672

Суть этого ответа применима к вашему вопросу. Ему нужно что-то делать, когда ему передается nil . Газлер указывает на то, что технически происходит, но ответ DHH показывает немного более высокий уровень «почему?» url_for Метод работает нормально, принимая нулевой аргумент, при этом текущая страница используется по умолчанию.