Article

Extending flash message functionality in Rails

Building a Rails application isn’t just about lean, pretty code; creating a clean and intuitive user experience always plays a key role in making your application a success. Luckily Rails has a lot of “out of the box” features already bundled from the word go which can help you to quickly achieve this goal.

One of the most common features is flash messages; these allow the application to provide feedback to a user after triggering an action. When I started building flash messages into Trado, I was quickly limited by the ability to only display one flash message at any given time. I wanted to display error messages as well as provide hints, so I decided to write my own solution.

In order to properly scope out my new solution, I needed to ensure I had a list of user stories which included current and new features. Here was the list I created:

I need to be able to…

  1. define the type of flash message, i.e. notice, success or error
  2. define a bespoke message for each flash
  3. add more the one flash message per page, without being limited
  4. order the flash messages
  5. retain clean code for the layout/controllers

I decided to retain a lot of the logic within the app/helpers/application_helper.rb file to keep both the layout and controller files clean and easy to maintain. Although, this solution provided a spanner in the works: controllers do not have any association with helper files. I didn’t want to include the ApplicationHelper in every controller which needed flashes, as that would go against the DRY principle, so I leveraged the inheritance between all controllers and the ApplicationController and included the ApplicationHelper only once. Here is my code so far:

app/controllers/application_controller.rb

app/helpers/application_helper.rb

This is quite a lot of code to take in at once, so I’ll break it up and walk you through it in more detail:

Here I have included the ApplicationHelper class into the ApplicationController class. All controllers inherit from the ApplicationController class, which in turn means all controllers now have access to the methods inside the ApplicationHelper class.

This is the method which will be used within controllers. I need to pass two parameters along with the method, the first defining the type of flash message with a symbol type (:notice, :success or :error) and the second containing your bespoke message for the flash.

Finally this method will iterate through each flash message, rendering the DOM elements with a partial and storing said partial into an array. This is then rendered to the page with a join and html_safe method to ensure all elements are formatted correctly.

Here is an example of the functionality in my layout and controller:

app/views/layouts/admin.html.erb

app/controller/admin/zones/countries_controller.rb

As you can see from above I have included the render_flash method in the layout view, and declared two separate flash_message methods in controller with different flash types – both of which will display if the country is saved successfully.

Wait! Now my Devise gem is throwing an error?

I was positively chuffed with my solution for a while, but soon enough Devise started throwing errors when attempting to display it’s built-in flash messages. The reason for this was Devise was still using the old solution of providing a single string flash message, and not using my custom flash_message method with it’s bespoke parameters. After a bit of digging and investigation, I knew it would easier in the long term to modify my custom flash methods to cater for single string flash messages (I’m never a fan of hacking apart gems as it makes upgrading them a ball ache).

The compromise in the end turned out to be quite simple. By adding a condition to the render_flash method, I was able to render a flash message differently if it was of type String – using the simple power of basic Ruby. Here is my finished render_flash method:

I hope this has been enlightening and helps you on your way to user-friendly applications. Any questions feel free to comment below.

08th July 2014

Any thoughts?

Your email address will not be published. Required fields are marked *

*


three × = 15

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">