Rails никоим образом не последовательны в использовании исключений. find
вызовет исключение, если объект не найден, но для сохранения вы можете выбрать, какое поведение вы хотите. Наиболее распространенная форма это:
if something.save
# formulate a reply
else
# formulate an error reply, or redirect back to a form, or whatever
end
т.е. save
возвращает истину или ложь. Но есть также save!
, который вызывает исключение (добавление восклицательного знака в конец имени метода является рубиизмом для того, чтобы показать, что метод «опасен», или разрушителен, или просто имеет побочные эффекты, то есть смысл зависит от контекста).
Существует веская причина, по которой find
вызывает исключение, однако: если исключение RecordNotFound
всплывает до верхнего уровня, это вызовет рендеринг страницы 404. Поскольку вы обычно не ловите эти исключения вручную (редко вы видите rescue ActiveRecord::RecordNotFound
в приложении Rails), вы получаете эту функцию бесплатно. Однако в некоторых случаях вы хотите что-то сделать, когда объект не существует, и в этих случаях вы должны поймать исключение.
Я не думаю, что термин «лучшая практика» на самом деле означает что-либо, но, по моему опыту, исключения не используются для управления потоком в Ruby больше, чем в Java или любом другом языке, который я использовал. Учитывая, что в Ruby нет проверенных исключений, вы имеете дело с исключениями гораздо реже.
В конце концов, дело до интерпретации. Поскольку наиболее распространенный вариант использования для find
- это получение объекта для его отображения и то, что URL для этого объекта будет создан приложением, вполне может быть исключительное обстоятельство, что объект не может быть найден. Это означает, что либо приложение генерирует ссылки на несуществующие объекты, либо пользователь вручную редактировал URL-адрес. Также может быть так, что объект был удален, но ссылка на него все еще существует в кеше или через поисковую систему, я бы сказал, что это тоже исключительное обстоятельство.
Этот аргумент применяется к find
при использовании, как в вашем примере, то есть с идентификатором. Существуют другие формы find
(включая множество find_by_*
вариантов), которые на самом деле ищут, и они не вызывают исключений (а затем в Rails 3 есть where
, который заменяет многие из вариантов использования find
в рельсах 2).
Я не хочу сказать, что использование исключений в качестве управления потоком - хорошая вещь, просто не обязательно неправильно, что find
вызывает исключения, и что ваш конкретный вариант использования не является распространенным случаем.