Rails NoMethodError в контроллере
Это в моем контроллере
def results
#searches with tags
@pictures = Picture.all
@alltags = Tag.all
searchkey = params['my_input']
pList = []
listsize = 0
while listsize < @pictures.size
pList[listsize] = 0
listsize += 1
end
@alltags.each do |tag|
if searchkey == tag.tagcontent
pList[tag.picture.id-1] += 1
end
end
@pictures.each do |picture|
if searchkey == picture.name
pList[picture.id-1] += 1
end
end
@pictures = @pictures.sort {|pic1, pic2| pList[pic2.id-1] <=> pList[pic1.id - 1]}
конец
эта ошибка возникает, когда это называется
NoMethodError в SearchController# результаты
У вас есть нулевой объект, когда вы этого не ожидали! Возможно, вы ожидали экземпляр Array. Ошибка произошла при оценке nil.+ Rails.root: /Users/kevinmohamed/SnapSort/server
Трассировка приложений | Framework Trace | Приложение Full Trace /controllers/search_controller.rb:31:in block in results'
app/controllers/search_controller.rb:29:in
каждый '
app/controllers/search_controller.rb:29: в `results'
31 - это pList[picture.id-1] += 1, 29 - это @pictures.each do |picture|, почему происходит эта ошибка
2 ответа
pList - это массив, проиндексированный с 0, 1, 2, 3, 4...
Ваша линия
pList[picture.id-1] += 1
может ссылаться на индекс, который не существует. Например, если pList имеет 50 членов, он имеет значения 0-49. Если идентификатор вышеупомянутого изображения 7891, то он попытается найти индекс 7890, который, конечно, не существует. Это вернет nil и попытается выполнить "nil += 1", отсюда ваша ошибка.
Возможно, pList должен быть хеш-кодом с идентификаторами картинок? Зависит от того, что вы пытаетесь достичь. Но что бы вы ни пытались сделать, почти наверняка есть менее подробный способ выразить это в Ruby.
Эта ошибка возникает, когда что-то, что вы перебираете, приводит к нулю, когда оно не ожидалось. У вас много кода в вашем контроллере. Я хотел бы предложить перенести часть этой логики в метод модели и написать несколько тестов для нее, включая выдачу ошибок, когда теги или рисунки недоступны. Затем вы можете сохранить ошибку в контроллере, чтобы отобразить более понятное сообщение об ошибке.