Rails 3.0/3.2: Вызывается id для nil, который по ошибке будет 4 - если вы действительно хотите идентификатор nil, используйте object_id
Я слежу за учебным пособием Кевина Скоглунда Ruby on Rails 3 Essential Training, который был написан для rails 3.0, хотя в настоящее время я использую 3.2. Он использует следующий метод в page_controller с параметром before_filter для отображения только страниц, принадлежащих родительскому объекту.
В учебнике явно используется .find_by_id, потому что если результат равен нулю, он "не вернет ошибку". Однако я получаю "Called id for no", который по ошибке был бы 4, если вам действительно нужен идентификатор id nil, используйте object_id "при попытке просмотреть страницу, где @subject был установлен на nil.
def find_subject
if params[:subject_id]
@subject = Subject.find_by_id(params[:subject_id])
end
end
Фактический код, вызывающий ошибку:
def list
@pages = Page.order("pages.position ASC").where(:subject_id => @subject.id)
end
Это что-то, что изменилось с 3.0? Если да, то каков был бы правильный способ реализовать эту функциональность в 3.2?
Ответы
Ответ 1
Сообщение:
"Вызывается id для nil, что по ошибке будет 4 - если вы действительно хотите идентификатор nil, используйте object_id"
Это стандартное сообщение в Rails, в котором говорится, что вы пытались вызвать .id
по значению nil
.
Итак, если @subject
равно nil, то это нормально, подходящее поведение для получения этого сообщения, если вы пытаетесь вызвать @subject.id
.
Я бы рекомендовал, чтобы в файле вида учитывалось, что @subject
может быть nil
и адресовать его в том, как вы представляете информацию. Посмотрите на код и подумайте, что вы должны представлять в представлении там, если @subject
есть nil
.
Ответ 2
Не имея кода, с которым вы работаете, я могу ошибаться. Но если вы используете
params[:id]
Для быстрой проверки просто поставьте это перед оператором if:
puts ">>> #{params[:subject_id]}"
Если он дает вам идентификатор, я ошибаюсь...
Ответ 3
Код, который вы вставили, скорее всего, не приведет к ошибке. По вашему мнению, вы, вероятно, показываете @subject.id
, который выдает эту ошибку. Вы должны получить трассировку стека, которая дает точную строку, в которой проблема включена.