Как я могу пропустить ошибку, если find ничего не возвращает в рельсах?
Я пытаюсь создать систему, в которой пользователь может видеть только статьи, которые он написал.
В контроллере статей я помещаю ниже строки
@article = current_user.articles.find(params[:id])
где params [: id] - article_id.
Я просто хочу знать, как я могу пропустить ошибку из отображения и просто перенаправить на: действие индекса, если статья не существует, или если у пользователя нет разрешения на просмотр.
Я положил @article.nil? условный оператор после инструкции find выше, но кажется, что вышеприведенный вывод вызывает ошибку, как показано ниже.
Не удалось найти статью с идентификатором = 1662 [ГДЕ (articles
.user_id = 1)]
Как я могу решить эту проблему?
Ответы
Ответ 1
ActiveRecord:: Base.find всегда выдает исключение, если оно не находит запись, это преднамеренно. Вы должны использовать только find
, если вы абсолютно ожидаете иметь то, что вы ищете. Если вы растеряете действие шоу и не можете найти статью, вы должны спасти это исключение и отобразить 404 (не найдено) вместо перенаправления на индекс (технически).
Если вы хотите что-то найти с помощью атрибута id
без принудительного исключения, используйте динамический finder find_by_id
, который вернет false, если он не найдет запись с этим идентификатором.
Edit:
У динамических искателей теперь есть другая подпись, find_by_id
теперь должна быть:
find_by :id, id_to_find
Смотрите новый Rails Guide on Querying
Ответ 2
Вы должны использовать find_by_id
или любой из методов, приведенных в этом question.
Ответ 3
Это связано с тем, что метод поиска ActiveRecord вызывает исключение, когда он не может найти определенный идентификатор. Вы можете решить эту пару способов, лучший способ, кажется,
begin
@article = current_user.articles.find(params[:id])
rescue
redirect_to articles_path
end
Ответ 4
Метод find() вызывает исключение RecordNotFound, тогда как методы, такие как find_by_id, возвращают значение nil. Таким образом, у вас есть пара опций, которые вы можете связать с вызовом метода start/rescue, добавьте блок rescue_from к контроллеру:
rescue_from(ActiveRecord::RecordNotFound) {|e| do something here }
или использовать метод find_by_id и обрабатывать условие, в котором возвращается nil.
На самом деле существует множество других альтернатив, но те, что выше, являются хорошим началом, причем find_by_id, вероятно, является самым легким.