Поскольку Ruby является чисто объектно-ориентированным языком, исключения играют большую роль в процессе управления. Ранее у вас был выбор спасения исключений на локальном уровне или вы могли переопределить метод rescue_action в вашем контроллере.
Первый метод дал вам очень детальный контроль над тем, что делать в случае исключения:
begin user.save! rescue ActiveRecord::RecordInvalid render :action => 'new' end
В этом случае, если возникнет исключение ActiveRecord :: RecordInvalid (метод save! Вызовет это в случае сбоя проверки) Rails отобразит действие «new». Стало ясно, что добавление begin / rescue к одним и тем же методам отнимает много времени и не очень СУХО, — вот где rescue_action стало полезным:
def rescue_action (исключение) если исключение == ActionView :: TemplateError render: template => 'errors / 404' еще супер конец конец
Этот (довольно надуманный) пример перехватит любой ActionView :: TemplateError и отобразит файл 404.erb в каталоге / app / views / errors. Вы можете добавить этот метод в любой контроллер (включая app_controller), но опять же, для их настройки требуется много работы, чтобы каждый контроллер выполнял правильное действие для данного исключения, поэтому в Rails 2.0 вводится rescue_from ,
rescue_from является атрибутом каждого контроллера и позволяет вам определять метод, который будет запускаться при вызове определенного исключения. Таким образом, приведенный выше пример станет:
rescue_from ActionView::TemplateError, :with => :render_404 def render_404(exception) render :template => 'errors/404' end
rescue_from ActionView::TemplateError, :with => :render_404 def render_404(exception) render :template => 'errors/404' end
или если вы предпочитаете использовать встроенный блок:
rescue_from ActionView::TemplateError do { render :template => 'errors/404' }
rescue_from ActionView::TemplateError do { render :template => 'errors/404' }
В текущем выпуске PR метод rescue_from может перехватывать только исключения точного типа, поэтому он не будет перехватывать подклассифицированные исключения — если у вас есть пользовательское исключение MyTemplateError, которое расширяет ActionView :: TemplateError, вышеуказанный код не будет работать , Хорошей новостью является то, что патч к краям рельсов решает эту проблему, поэтому релизная версия Rails 2.0 будет работать так, как ожидается.