Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

flash loses messages on redirect

#4082

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

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

State: invalid
Milestone: none
Assigned to: nobody
Importance: none

Activity

  1. José Valim
    José Valim
    • 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.

    March 3rd, 2010 @ 08:36 AM

  2. Greg Hazel
    Greg Hazel

    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.

    March 3rd, 2010 @ 09:18 AM

  3. Greg Hazel
    Greg Hazel

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

    January 23rd, 2011 @ 12:10 PM