Метод Rails Игнорирование параметра по умолчанию - ПОЧЕМУ? - PullRequest
4 голосов
/ 21 мая 2011

Я в недоумении, почему это происходит. У меня есть следующая функция:

def as_json(options = {})
  json = {
    :id => id,
    # ... more unimportant code
    }
  unless options[:simple]
    # ... more unimportant code
  end
  json  
end

Это работает большую часть времени, но в одном частичном, где я называю это:

window.JSONdata = <%= @day.to_json.html_safe %>

Я получаю следующую ошибку:

ActionView :: Template :: Error (У вас есть нулевой объект, когда вы этого не ожидали! Возможно, вы ожидали экземпляр Array. Произошла ошибка при оценке nil. []):

Указание на строку «если только опции [: simple]». Насколько я могу судить, хэш опций равен nil, поэтому метод игнорирует присвоение параметров по умолчанию. ЗАЧЕМ? Я могу это исправить, изменив метод на:

def as_json(options)
  options ||= {}
  json = {
    :id => id,
    # ... more unimportant code
    }
  unless options[:simple]
    # ... more unimportant code
  end
  json  
end

Имеет ли это какой-либо смысл для кого-либо !? Наиболее признателен за вашу помощь.

1 Ответ

3 голосов
/ 22 мая 2011

Это потому, что вы используете to_json, который по умолчанию options равен nil. to_json в конце концов вызовет as_json и передаст nil как options.

Вот где это происходит в исходном коде Rails. Во-первых, to_json определяется по умолчанию options из nil.

# https://github.com/rails/rails/blob/v3.0.7/activesupport/lib/active_support/core_ext/object/to_json.rb#L15
def to_json(options = nil)
  ActiveSupport::JSON.encode(self, options)
end

В конце концов он прибудет сюда.

# https://github.com/rails/rails/blob/v3.0.7/activesupport/lib/active_support/json/encoding.rb#L41
def encode(value, use_options = true)
  check_for_circular_references(value) do
    jsonified = use_options ? value.as_json(options_for(value)) : value.as_json
    jsonified.encode_json(self)
  end
end

Как видите, as_json вызывается с value.as_json(options_for(value)), а options_for(value) вернет значение по умолчанию to_json, то есть nil.

...