Creating Multiple Flash Messages in Ruby on Rails

On my Flight Historian application, a number of my pages make use of the flash and flash.now session messages capability for errors, warnings, successes, and informational messages. However, some of those pages needed to have multiple messages of the same type (e.g., multiple warnings), which flash didn’t allow me to do. Additionally, I had some views that were generating status messages of their own (for example, if a collection was empty on a page that had multiple collections), and so I ended up with several ways to generate messages that didn’t output consistent HTML.

Multiple Messages

To fix this, I wrote my own messages structure.

Message Partial

I first created a message partial which would render an individual message banner:

This partial accepts a message type (error, warning, etc.) which is used to select the CSS class, and the message text.

render_message

In order to shorten the partial call, I wrote a render_message(type, text) method in the application helper to call the partial:

If necessary, I can call this directly from the view to insert a message anywhere I want. However, I also need to be able to have controllers add messages to be displayed at the top of the page.

add_message

I created an add_message(type, text) method in the application controller which creates an array of message hashes (if one doesn’t already exist) and allows me to add messages to it.

render_messages

Now, I need to display all messages. Back in the application helper:

Since my messages can have different priorities, when I display a page with multiple messages, I want them sorted with the highest priorities first. My order array defines the order I want my types sorted in.

Next, I make sure a @messages array exists, and then I merge any flash messages into my messages array, so they display the same as any other message. For each flash, the hash’s key is used as the type.

Then, I get the index of each message type in my order array, and sort on that. If a message has a type that’s not in the array, it’s given an order number of the length of the array. Since that number will always be higher than any array index, the unknown message types will be sorted below the defined message types.

Finally, I loop through the messages with map, call render_message to render the message partial for each, and then join all the partials together. Since this is the last operation of the method, this string of joined message partials will be returned by render_messages.

Application Layout

Finally, I call render_message at the top of the page in my application layout:

The end result works well. Here, I’m explicitly mixing a status message from my controller (yellow) with a flash message from a database update (green):

Multiple Messages New

And that’s it! I wish the flash itself supported having multiple messages of the same type, but since it doesn’t, this works well for me.

Advertisements

One thought on “Creating Multiple Flash Messages in Ruby on Rails

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s