Effectively using rescue_from
Even though Ryan Daigle already covered it in his usual timely fashion, I’d like to share some real life examples of how we use the relatively new rescue_from functionality.
Because I usually prefer methods that raise exceptions instead of returning a boolean, like, say, save! instead of just save, I thought it would be nice if I could deal with some common exceptions on a higher level. This lead me to write a Rails patch based on the exception_handler plugin, which I previously used in some projects.
class PostsController < ApplicationController
def create
@post = Post.create!(params[:post])
rescue ActiveRecord::RecordInvalid
render :action => :new
end
def update
@post = Post.find(params[:id])
@post.update_attributes!(params[:post])
rescue ActiveRecord::RecordInvalid
render :action => :edit
end
end
to something like this:
class ApplicationController < ActionController::Base
rescue_from ActiveRecord::RecordInvalid do |exception|
render :action => (exception.record.new_record? ? :new : :edit)
end
end
class PostsController < ApplicationController
def create
@post = Post.create!(params[:post])
end
def update
@post = Post.find(params[:id])
@post.update_attributes!(params[:post])
end
end
And it just works.
Comments
Add your comment
In order to fight spam on this blog, posting comments from a browser without javascript is currently not supported.
Subscribe
Remco about 24 hours later: (delete)
The update action rendering an edit, in case of an exception, will not have @post properly set. ¶
Norbert Crombach 1 day later: (delete)
Good catch. ¶
jare care 1 day later: (delete | show email)
This example is terrible.
First off remember this:
"exceptions should not be expected"
Your tendency of avoiding boolean methods like #save in favor of exception raising methods like #save! is conveying the message that invalid data is something you do NOT expect.
That is wrong. Of course you expect invalid data, therefore that should NOT be handled using exceptions but instead using boolean methods and conditional logic.
Your use of the ternary operator in your #rescue_from block is an example of DRYness going too far. The more "DRY" you try to keep that controller the more conditional logic you're going to have to add in your #rescue_from block. Thats going to get ugly real quick.
For more info check out http://giantrobots.thoughtbot.com/2007/9/26/active-record-programming-with-exceptions ¶
Manfred Stienstra 2 days later: (delete)
We've been having some discussion here at the office about how to properly structure a controller these last days. My (and Thijs') argument against this kind of logic is that it doesn't read like a story any more because you scatter the logic throughout the code. Remember GOSUB?
Norbert has been working on a way to get something like this working without loosing readability. ¶
Bala Paranj 195 days later: (delete | show email)
How will you set the flash message? ¶