Статьи

Подготовка к Rails 2.0: обработка исключений на основе контроллера

Поскольку 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 будет работать так, как ожидается.