How to Integrate Flash Messages in Rails

What are Flash Messages?

According to Ruby Guides, a flash message is a way to communicate information with the users of your Rails application so they can know what happens as a result of their actions. We can use flash messages to display the user either if they have successfully created an account, or even if there are any missing fields within the text fields.

How to use Flash Messages?

May be simple as it seems. Flash messages behaves like a ruby hash. Messages can be accessed with , and flash object also has methods like keys, any? and each. In order to invoke a flash message, we have to start within our controller. Let’s start with creating a new Student. Within our students_controller, on our create action, we may have something like this:

def create@student = Student.new(student_params)if @student.savesession[:student_id] = @student.idredirect_to student_path(@student)elseredirect_to '/signup'end
end

We are going to create a new flash message if the student does not save. Like I stated previously, the flash object is like a ruby hash. In order to create a new key in that hash we would have to call the flash object with the key you want to add and the message. In other words, look at this example below:

flash[:message] = "Missing Fields" 

Let’s add this to our Students#Create action, and lets add if the Student was successfully created as well:

def create@student = Student.new(student_params)if @student.savesession[:student_id] = @student.idredirect_to student_path(@student)
flash[:message] = "Your Account was Created Successfully!"
elseredirect_to '/signup'
flash[:message] = "Missing Fields"
end
end

Excellent! Is there anyway we can shorten this out? Yes there is! Let’s take a look below:

def create@student = Student.new(student_params)if @student.savesession[:student_id] = @student.idredirect_to student_path(@student), :message = "Your Account was Created Successfully!"elseredirect_to '/signup', :message = "Missing Fields"end
end

Ok, now how do we render this within our views. We would have to invoke our flash object and see if there are any errors, then display our message. We can do so by adding this within our view:

<% if flash.any? %>
<% flash.each do |type, msg| %>
<div>
<%= msg %>
</div>
<% end %>
<% end %>

This is good so far, but putting this within every view will be a ton of work and a lot of repetition. Our goal as software developer is to keep our code clean and less repetitive. We want to keep our code DRY( Don’t Repeat Yourself). How can we achieve this? We can achieve this by adding a partial.

What is a Partial?

On Ruby Documentation, Partial templates — usually just called “partials” — are another device for breaking the rendering process into more manageable chunks. With a partial, you can move the code for rendering a particular piece of a response to its own file.

Let’s create a partial for our flash messages. Within our views/layouts, lets create a new file name ‘ _flash.html.erb’ and lets cut out out flash messages code and paste it in our partial.

Your _flash.html.erb partial should look like this:

<% if flash.any? %>
<% flash.each do |type, msg| %>
<div>
<%= msg %>
</div>
<% end %>
<% end %>

How can we render our partial within our view? According to Ruby Documentation, To render a partial as part of a view, you use the method within the view:

<%= render "menu" %>

This will render a file named at that point within the view being rendered. Note the leading underscore character: partials are named with a leading underscore to distinguish them from regular views, even though they are referred to without the underscore. This holds true even when you're pulling in a partial from another folder.

In our case because our flash partial is in our layouts directory within our views, we would have to render from our layouts directory. So our render should look like this:

<%= render "layouts/flash" %>

Excellent! This will work and display you flash messages again! If it does not, check which directory you have your flash, and make sure when rendering a partial you have the ‘=’ sign, because this is what you want to display.

Issues

1: I have followed all these steps and still not have had my flash messages rendered, why?

There can be several reasons why.

The first one, check your directory if it is the correct path.

The second one, making sure you have the ‘=’ sign

The last thing is this. The Flash Object comes with default values such as flash[:notice], and flash[:alert]. Because flash[:messages] is not a default, we have to add our custom flash keys in our Application Controller by adding this:

class ApplicationController < ActionController::Baseadd_flash_types :danger, :info, :warning, :success, :messagesend

Make sure you have these keys invoked in our Application Controller, especially if you want to add Bootstrap.

Bootstrap

Different Options for Alerts

Now that we understand what Flash is and how we can invoke them by partials, and even add custom flash types, we are going to add bootstrap for styling!

We are going to change our partial from this:

<% if flash.any? %>
<% flash.each do |type, msg| %>
<div>
<%= msg %>
</div>
<% end %>
<% end %>

To this:

<% if flash.any? %>
<% flash.each do |type, msg| %>
<div class=”alert alert-info”>
<%= msg %>
</div>
<% end %>
<% end %>

This would give you every flash message to be like a faded blue color. According to Bootstrap, there are many more different alerts. What if we want our flash alerts to be Red if the User/Student was ‘Missing Fields’, or to display Green if a New ‘Student was Successfully Created’? How can we make our flash partial more dynamic to use? Well, we can do this!

Let’s start by remembering that you have added your custom flash types in your Application Controller. Have you invoked them in your controller yet? Well, lets do so. Lets change our Students#Create from this:

def create@student = Student.new(student_params)if @student.savesession[:student_id] = @student.idredirect_to student_path(@student), :message = "Your Account was Created Successfully!"elseredirect_to '/signup', :message = "Missing Fields"end
end

To This:

def create@student = Student.new(student_params)if @student.savesession[:student_id] = @student.idredirect_to student_path(@student), :success = "Your Account was Created Successfully!"elseredirect_to '/signup', :danger = "Missing Fields"end
end

According to Bootstrap, danger would display a red ribbon, and success would display a green ribbon. Also, please make sure you add your flash types in your Application Controller, it should look like this:

class ApplicationController < ActionController::Baseadd_flash_types :danger, :info, :warning, :success, :messagesend

Next, we are going to change our flash partial from this:

<% if flash.any? %>
<% flash.each do |type, msg| %>
<div class=”alert alert-info”>
<%= msg %>
</div>
<% end %>
<% end %>

To This:

<% if flash.any? %>
<% flash.each do |type, msg| %>
<div class=”alert alert-<%= type %>”>
<%= msg %>
</div>
<% end %>
<% end %>

Check this out: Put in a binding.pry and lets analyze

<% if flash.any? %>
<% flash.each do |type, msg| %>
<% binding.pry %><div class=”alert alert-<%= type %>”>
<%= msg %>
</div>
<% end %>
<% end %>

Type in your terminal flash. You will get the flash object returned with the type and the message. Now try typing in ‘type’ you should get the type either, success, or danger. This type will be replaced in your partial. Example:

<div class=”alert alert-<%= type %>”>

To This:

<div class=”alert alert-danger”>

Bootstrap will automatically generate the ribbon. This will make your flash messages more dynamic, and make your partials more useful with keep your code DRY. If you need any more assistance, I personally recommend to CLICK HERE, or click the link below to watch a tutorial on integrating bootstrap on Flash Messages.

Hope this was helpful! Thank You!