Rack Flash

The Flash

Rails has a nice little hash called the Flash - it’s not a Super Hero that can run fast, just a neat way temporarily storing messages to inbetween requests. For example if something happens in your app (a note is saved for example) and then you redirect the user to another page then you could store a message in the flash saying that the note had been saved. This message would then be shown on the next page (after the redirect).

You can get the same functionality in Sinatra by using Rack Flash.

All you need to do is install the gem:

sudo gem install rack-flash

Then in your Sinatra app, you will need the following lines of code:

require 'rack-flash'
use Rack::Flash
enable :sessions

(Rack Flash is uses sessions to store the hash and they are disabled by default in Sinatra)

To use the flash hash, you just set the message in the handler, for example:

post '/notes/save' do
  flash[:notice] = "Your note has been saved"
  redirect '/'
end

Then you put a reference to the message in your view (assuming you are using erb):

<div id='flash' class='notice'>
  <%= flash[:notice] %>
</div>

Now when somebody saved the note, they would see the message when they are redirected to the index page (’/’).

Notice that you can associate a key with the flash message to differentiate between different types of message. Some examples are:

flash[:notice]
flash[:warning]
flash[:error]

If you want to display the flash in the current request, use flash.now

get ’/’ do flash.now:notice=’No Messages’ unless flash:notice end

This will display a message that there are no messages there isn’t a message stored in the flash already from the previous request.

A message will stay in the hash until it is displayed, as can be seen in this example:

get '/one' do
  flash[:notice]='Hi!'
  flash[:error]='type 1 error'
  flash[:warning]= 'Beware of the dog'
  redirect '/two' 
end

get '/two' do
  flash[:error]='type 2 error'
  redirect '/three' 
end

get '/three' do
  flash[:notice]='Goodbye!'
  erb :index
end

By the time we get to ‘/three’ and the index view is displayed, flash[:error]='type 2 error', flash[:notice]='Goodbye!' and flash[:warning] is still ‘Beware of the dog’.

If you don’t want the messages to hang around in the flash until they are used, you can get rid of them by setting the sweep option:

use Rack::Flash, :sweep => true

This will ensure that the flash is wiped clean after each request, whether it is displayed or not (In the example above, the only entry left in the flash by ‘/three’ would be flash[:notice]='Goodbye!'.

Here’s a useful snippet of erb that you can put in a layout. It will display a flash message if there is one and give it a class name depending on the type of message:

<% %w[notice error warning alert info].each do |key| %>
  <% if flash[key] %>
    <div id="#{key}" class="flash">
      <%= flash[key] %>
    </div>
  <% end %>
<% end %>

In Haml, this will look like this:

- %w[notice error warning alert info].each do |key|
  - if flash[key]
    %div{:id => key,:class => "flash"}= flash[key]

Or in Slim:

- %w[notice error warning alert info].each do |key|
  - if flash[key]
    div.flash id=key == flash[key]

This will create a new div, with a class corresponding to the key (notice, error, warning, alert or info) for each message that you have stored in the flash hash.

I hope you found this useful - many apps use this brilliant little gem for notifications, so why not try it in one of yours?

blog comments powered by Disqus