This project is archived and is in readonly mode.

#4082 ✓invalid
Greg Hazel

flash loses messages on redirect

Reported by Greg Hazel | March 1st, 2010 @ 11:56 PM

The FlashHash discards messages if the hash is ever touched in the action, even if the only operation is to add another message. Consider:

class ThingController < ApplicationController

  def login
    flash[:info] = "Welcome back!"
    # for this example previous_location will be good_times, but it could be any path on the site
    redirect_to current_user.previous_location
  end

  def good_times
    flash[:error] = "Good times are over!"
    redirect_to :action => :homepage
  end

  def homepage
    # XXX: observe the "Welcome back!" message is not present.
    logger.warn flash.inspect #=> {:error=>"Good times are over!"}
  end

end

The expected behavior is that both the info and error messages would be kept until they are displayed. If the error message is removed, the info message makes it all the way to the homepage.

I understand why this is occurring - FlashHash marks all items as "used" any time the "flash" accessor method is used. This however does not correlate to actually displaying the messages, as this example shows. It is possible to hack around this by adding flash.keep to good_times, but if this could be any location on the entire site that means adding flash.keep in front of all redirects. So, correct usage seems difficult.

I can think of two obvious ways to solve this:

  • extend redirect_to to always call flash.keep

or:

  • fix FlashHash to only mark messages as used on [] access

Comments and changes to this ticket

  • José Valim

    José Valim March 3rd, 2010 @ 08:36 AM

    • State changed from “new” to “invalid”

    As far as I know, this is the expected behavior. Flash messages are supposed to be shown in the next request. If you have double redirects, you are responsible for keeping them.

  • Greg Hazel

    Greg Hazel March 3rd, 2010 @ 09:18 AM

    Well, isn't it a bug then that they are not kept if you do not touch the "flash" accessor method?

    class ThingController < ApplicationController
    
      def login
        flash[:info] = "Welcome back!"
        # for this example previous_location will be good_times, but it could be any path on the site
        redirect_to current_user.previous_location
      end
    
      def good_times
        redirect_to :action => :homepage
      end
    
      def homepage
        # XXX: observe the "Welcome back!" message is present.
        logger.warn flash.inspect #=> {:info=>"Welcome back!"}
      end
    
    end
    

    Personally though, the semantics of the flash hash discarding unused data are not useful. Display once-and-only-once semantics would be much better / less surprising.

  • Greg Hazel

    Greg Hazel January 23rd, 2011 @ 12:10 PM

    Indication that the interface is a bit more cumbersome than people expect: http://www.rubysavedmylife.com/2007/12/15/flashnotice-vs-flashnowno...

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

People watching this ticket

Tags

Pages