Ensuring the displaying of flash messages in Ruby on Rails

Ruby on Rails has a special object called flash which hold its contents for one more request. It’s particularly useful to show messages after a redirect. Since it’s good style to redirect after each succesful form post, that’s where you put the messages such as: “You’ve logged in”, “Thank you for your feedback”, “The book has been added”, etc.

This flash object looks like a hash table. I normally use two items in there: notice, for good stuff and errors, for bad stuff. I want these messages to be displayed in all pages, so whenever something bad or good happens, I just drop stuff in the notice or error and forget about it. This is trivial to do, I just put this:

<% if flash[:error] -%>
  <p class='error'><%=h flash[:error] %></p>
<% end -%>
<% if flash[:notice] -%>
  <p class='notice'><%=h flash[:notice] %></p>
<% end -%>

on the application layout.

The problem with doing that is that it doesn’t look nice. I expect error messages and success messages to be near the forms or UI elements I’m interacting with. That means that every view or page will put it in a different location. No problem, you just add that same snippet where you want the messages to appear.

Then there’s a second problem: you get messages twice. If you remove them from the application layout, then you have to remember to put in absolutely every view, even those that you don’t expect to never show an error or notice. I don’t trust myself to always remember to do anything, so what happens is that I can’t just drop something in the flash and expected it to be show, I have to check every time.

I’m doing this in for a pet projects with less than 10 views, but I think big. I think of the project having 100 views and three coders than don’t know all the implicit rules, like adding the display message snippet to every view they create.

I’ve came up with this solution. I created a partial view with this content:

<% if not @messages_rendered -%>
  <% if flash[:error] -%>
    <p class='error'><%=h flash[:error] %></p>
  <% end -%>
  <% if flash[:notice] -%>
    <p class='notice'><%=h flash[:notice] %></p>
  <% end -%>
<% end -%>
<% @messages_rendered = true -%>

That partial view is rendered from the views and also from the application layout, but it displays the messages only once. Thankfully Rails renders the partials inside the views first, so that the messages gets displayed according to the view, and if the view didn’t display them, the application layout will.

Advertisements

One Reply to “Ensuring the displaying of flash messages in Ruby on Rails”

  1. Hi,

    tank you. Can you maybe explain how you add the error message or the notice in the model?
    I have a model where I want to add and error “product has tasks and cannot be deleted” in a product model. Do you have to use add to base to add the error messages?

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