Flash bug or feature?

I posted this to the talk mailing list but got no response, not sure if this list is more suitable.

As the subject suggests, I’m not sure if this is a bug or a feature.

If I have an action that sets something in the flash and redirects to an action (to pre-empt the “flash.now” responses) that renders something but does not touch the flash at all then the values will remain in the flash for following requests to pick up. This could potentially be an infinite number of requests later if none of the requests in between touch the flash.

I believe this is because Request.flash is lazily loaded but only swept (as a side effect of to_session_value) if it has been lazy loaded.

Touching the flash in anyway (even without using it) will produce the behaviour I expect of the flash being cleared in the request following the redirect and so no further requests being able to access it. This means I can use an after_action or similar to ensure it is always loaded and get the behaviour I expect.

Is the current behaviour expected?

If it is, I have a work around and hopefully this will exist on Google for other people who expect it to work as I do. If it isn’t, I’m happy to look into it and create a pull request.

Cheers,

Garry

It’s deliberate - if you don’t access the flash, then you clearly haven’t rendered the message, so it should stay until a request that does.

Otherwise any random request (say an AJAX autocompleter) that happens to come in before the next page request (which is the one we intend to show the flash message) will steal the flash value and throw it away.

There was another problem with clearing the flash hash on every request. There was a period when rails did do this, and it caused a massive security problem for one of my projects: hitting the flash meant accessing the session variable, and since the ability to explicitly turn off the session in certain controllers was removed a long time ago, this meant that all requests accessed the session variable. Which meant they all wrote the session variable, because Rails writes the session cookie back out if the session was loaded. Which meant if you had a request that said the response was cacheable, all the users hitting that action got the cached session cookie of some other user…

More generally, it’s not intended that all controller actions will load and set the session, even if they don’t use it. It’s supposed to be lazy-loaded as you say, and that means the flash is too.

I don’t understand why you are putting stuff into the flash hash if you don’t actually want to render it again though? It’s specifically there to put stuff into the session to be renderd by the next layout request.

Just use an ordinary ivar if you don’t want that.

Indeed, this effect has existed since the early days of Rails. It is so much a part of Rails’ legacy that most of the non-technical people I work with are aware of it as an artifact of Rails specifically.

-Jason

I’m using the flash to indicate that the user has been redirected from a certain action (so ivars won’t work) in a way that can’t be tampered with (so can’t attach a query string parameter).

Only a subset of the targets that might be redirected to (potentially anywhere in the site) behave differently in this case, and so the flash seemed the obvious place to put this flag as it would (without the subtle difference between the documented and actual behaviour) exist in a secure location for the duration of the redirect before being removed.

We don’t use the flash in all our layouts and so a “full render” (I can see the edge case with concurrent AJAX requests being problematic) doesn’t necessarily touch the flash at all to cause this temporary flag to be evicted.

As mentioned, I’ve found a workaround for my situation. I thought I’d raise the question as it seemed potentially unintentional, but as it’s the expected behaviour it’s a feature not a bug :slight_smile:

Thanks for the responses.