#ruby-on-rails #ruby-on-rails-3 #methods #parameter-passing
#ruby-on-rails #ruby-on-rails-3 #методы #передача параметра
Вопрос:
Я в недоумении относительно того, почему это происходит. У меня есть следующая функция:
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::Ошибка (У вас есть объект nil, когда вы этого не ожидали! Возможно, вы ожидали экземпляр Array. Ошибка произошла при вычислении nil.[]):
Указывая на строку «если параметры [:простые]». Насколько я могу судить, хэш параметров равен нулю — таким образом, метод игнорирует назначение параметра по умолчанию. ПОЧЕМУ? Я могу исправить это, изменив метод на:
def as_json(options)
options ||= {}
json = {
:id => id,
# ... more unimportant code
}
unless options[:simple]
# ... more unimportant code
end
json
end
Имеет ли это какой-либо смысл для кого-нибудь!? Очень признателен за вашу помощь.
Ответ №1:
Это потому, что вы используете 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
равно.
Комментарии:
1. Большое спасибо за отличный ответ — он был действительно четким и информативным!
2. Последний вопрос. Я попытался вызвать to_json с помощью консоли, прежде чем опубликовать этот вопрос, чтобы узнать, была ли проблема с этой функцией. Однако в консоли как to_json, так и as_json работали нормально. Есть идеи, почему консоль не сгенерировала ошибку?
3. Для меня на консоли он ведет себя так, как ожидалось. Возможно, вы не перезагружали консоль, чтобы отразить код в тот момент.
4. Вероятно, вы правы насчет перезагрузки. Еще раз спасибо за помощь!