I know I said I was going to try and keep the features in "a feature a day" to those not mentioned in popular places, but this feature is one of the few nicest features in Rails made by a contributor outside of the Rails core so I couldn't resist mentioning it.
First, an example
class CommentsController < ActionController::Base rescue_from Comment::Spammy, :with => :moderate_comment rescue_from ActiveRecord::RecordNotFound, :with => :redirect_if_not_found protected def moderate_comment # Handle the exception, like placing the comment in a moderation queue # and then rendering a different action. end def redirect_if_not_found # Redirect somewhere... end end
Compare this to what you had to do with Rails 1.2.6 and earlier:
class CommentsController < ActionController::Base def rescue_action_in_public(exception) case exception when Comment::Spammy # Handle the exception as above. when ActiveRecord::RecordNotFound # Redirect somewhere... else super end end end
Much clearer and reads almost like English. I don't think I even need to explain what the code in the 1st example is trying to do.
Let's try another example
Here's another common use-case: dealing bad create/update actions. With
rescue_from, you can simply do this:
class ApplicationController < ActionController::Base rescue_from ActiveRecord::RecordInvalid do |exception| render :action => (exception.record.new_record? ? :new : :edit) end end
No need for actions to be coded like this anymore!
def create @comment = comment.create!(params[:comment]) rescue ActiveRecord::RecordInvalid render :action => :new end
This patch was committed in revision 7597 after a short discussion on the syntax and implementation over at the ticket. (More improvements on the implementation over at ticket #9645 for the interested.)
About the contributor, Norbert Crombach
Norbert Crombach (Rails Trac username: norbert, WorkingWithRails profile) is another regular Rails contributor hailing from the Netherlands. The
rescue_from is, in my opinion, one of his more significant contributions (and what a great one it is too).
Some final words
While the new declarative
rescue_from macro is useful, I've found myself liking the merb way of dealing with exceptions, where exception handling is delegated to an Exception controller. You can use layouts, templates, helpers and filters just like in ye plain olde controller. I'm still not so sure if it's worth making a patch for Rails to emulate this behavior yet though!