You're just starting on rails and you're very excited about the ease of flash[:notice]. But every now and then, you set a flash notice and it seems to follow your clicks to the next action when it shouldn't. Why? I'll tell you.
Intro to flash[:notice]
flash[:notice] belongs to FlashHash.The basic use of the flash hash is flash[:notice], a place to put a message that describes the result of an action in a rails app. Let's look at an example:
class WeblogController < ActionController::Base def create @post = Post.new(params[:post]) if @post.save flash[:notice] = "#{@post.title} has been created." else flash[:notice]= "#{@post.title} could not be created." end end end
Pretty self explanatory. However, things get a bit complicated when you think about what that method should be doing. If the post is successfully created, the method should redirect_to post_path(@post), else, render :action => "new". The new action will fill the form in using the already initialized @post object (and it's errors) and the flash message will let them know that there was a problem. So let's add that in real quick:
class WeblogController < ActionController::Base def create @post = Post.new(params[:post]) if @post.save flash[:notice] = "#{@post.title} has been created." redirect_to post_path(@post) else flash[:notice]= "#{@post.title} could not be created." render :action => "new" end end end
Now flash[:notice] becomes a problem. When the user sees there was an error creating the post, he decided to abandon the process and move onto a different page in your application. Well, what's going to happen is that on the next page, he is going to see the same flash[:notice] he just saw notifying him of the error.
Flash Right Now
The Flash hash by default persists to the next action. That's what it's suppose to do - it's a way to send a message to the next action. However, in our create post example, if the post fails creation, there is no next action, rather, the create action simply renders the new action, a very common pattern. That's why when the user moves to another page, the flash[:notice] persists, because that other page is the next action. Obviously, you want to avoid that, and that's exactly what flash.now is for:
class WeblogController < ActionController::Base def create @post = Post.new(params[:post]) if @post.save flash[:notice] = "#{@post.title} has been created." redirect_to post_path(@post) else flash.now[:notice]= "#{@post.title} could not be created." render :action => "new" end end end
A basic rule to know when to use flash[:notice] and when to use flash.now[:notice] is if the action is redirecting - redirect_to - use flash[:notice], if it's rendering - render :action - use flash.now[:notice]. This is really just the beginning of the power of the flash object. Stay tuned for some more posts on how to really make use of this great feature in rails.
Trackbacks & Pingbacks 2
[…] previously discussed the difference between flash.now[:notice] and flash[:notice]. I ended with a summarizing rule that says when you end an action with render, you generally want […]
[…] key is the flash.now (see this page. Basically, using a redirect_to on the else means you loose your post values, so changing to render […]
Post a Comment