properly using the flash
Posted on 06/10/2009

No, I'm not going to tell you how to seduce the comic book superhero with an evening of dinner, cocktails, and smooth talk while demonstrating impeccable manners and etiquette.
What I am going to tell you is how to correctly use the handy Rails tool for passing objects between actions. Now, this is no huge secret or stunningly clever trick. In fact, you probably already know what I'm about to tell you. It's just one of those things that I never think to do until after it's a problem.
In the typical Rails app, there a snippet/partial/whatever that displays anything from the flash hash with either :notice or :error keys. If, in your controller action, you set flash[:notice] equal to some message and then redirect to another action, that message will persist through the redirect and get displayed on the subsequent view.
Here's the problem. If, in your action, you just render a view template instead of redirecting, then the user will see that message like you intended but it will also still remain on the following request which may or may not be confusing. Fortunately, there's an easy way to avoid this.
If you know you'll be redirecting, then there's nothing to worry about. Business as usual. But if you're not redirecting, just rendering a view, then you can use flash.now[:key]. The 'now' method only maintains the flash contents through the current request and is cleared before the next action. Check it out.
def create
@thing = Thing.new(params[:thing])
if @thing.save
flash[:notice] = "Oh snap! You created a thing!"
redirect_to @thing
else
flash.now[:error] = "Damn dog, you messed up"
render :action => :new
end
end
Notice how when the thing save without errors we use flash[] and redirect, but when there are errors we use flash.now[] and there's no redirect. This will keep your app users from seeing any strance, out of place errors.
So that's it. Like I said, it's nothing monumental. As you were...

