Back in a Flash: Using Flash Messages in your Ruby on Rails apps

Recently, I was introduced to flash — no, not Barry Allen (though I’d be interested if he could help with my NYC commute) — while learning about basic Rails CRUD apps. For those not in the know, flash is a Rails method with which you can render saved messages and information in the next full-page reload of your browser. Flash certainly seemed mystifying and, frankly, like a bit of Rails magic… since HTTP is stateless and doesn’t require the server to persist session data for each client past multiple full-page reloads (cookies being a different beast altogether). But with a bit of additional code, it’s easy to utilize flash magic for yourself. With the appropriate gems, you could also implement flash with Rack and Sinatra, though similar functionality can also be found with Javascript.

Here, we’ll focus specifically on its capabilities within Ruby on Rails and how you can employ flash within your fullstack apps.

Statelessness (or: Help, I’m Lost and Can’t Find my Way out of the Internet)

Photo by Javier Mazzeo on Unsplash

The reasoning for statelessness is that a significant amount of storage would need to be allocated to track the information related to every conversation in process, and then further, a process designed to remove those finished or canceled sessions which would otherwise still be saved. By doing so, the speed at which every full-page reload occurred would be drastically diminished. Think of it this way: if Twitter had to remember every session for every one of it’s 326mm active monthly users, on top of the 500mm new tweets created every day, …it would be a giant, slow behemoth of an application. Definitely slower than Limewire and sloths.

A quick aside: the internet layers stateless and stateful protocols on top of each other: IP lays the foundation, then TCP, then HTTP on top. Other protocols can be layered above HTTP, but HTTP itself has workarounds (again: cookies) to persist session data.

FLASH: What, Where, and How

In order to implement flash in your own apps, there’s a specific set of steps that must be taken.

  1. You first call and set flash in your action controller. You must tell flash precisely what you want it to persist forward.
  2. Redirect your action controller to the full-page reload of your choice.
  3. If you want to display that saved data in the rendering of your chosen full-page reload, you first confirm if anything has, in fact, been sent forward through flash, and then iterate through the available data in order to display it in the browser.

Through these steps, you can temporarily persist data forward to the client. The most common use for flash that I’ve seen thus far is to render error messages (did you actually enter a valid email?). Each time you ask a client to complete a form with validations and they fail to complete it accurately, your page would otherwise re-render and lose that error data if you didn’t persist that information in flash.

Putting Flash to Work

#app/controllers/wonkas_controller.rb1  class WonkaController < ApplicationController 
2 def index
3 flash[:snozberries] = "The snozberries taste like snozberries!"
4 end

So here, we have a Wonkas Controller, which is inheriting from the larger built-in, Application Controller. We’ve defined an action, index, that is assigning the string, “The snozberries taste like snozberries!” to flash with the symbol of :snozberries. This string is the data that we’re asking flash to persist. Next, we have to actually call the flashed data into a view.

1 <h1> Welcome to the Chocolate Factory </h1>
3 <%=flash[:snozberries] %>

Here in our index view, we’re simply setting a title, “Welcome to the Chocolate Factory” and then calling the flashed data. That’s it!

Now, perhaps you’d like to persist some error messages. One of flash’s built-in convenience accessors is errors (along with alert and notice). In this example, we’ll validate some of the attributes for a model, which can create errors when the client doesn’t create a valid instance of the model, parse those errors into flash, and render those flashed errors to the client when it reloads the form to create an instance.

In this example, we have some dogs — maybe Labradors, perhaps Great Danes, but maybe also …Dalmatians.

class Dog < ApplicationRecord
belongs_to :breed
validates :name, uniqueness: true

We have a Dog class that belongs to Breed and our model will validate that every new dog instance must have a unique name. Now, if we shift our view to the dogs_controller, you can see that we have a method here to create a new dog form and to then create a new dog instance. The new action will not only create a new dog instance for the create action to validate, but also call upon all of the breed instances so that it can select a breed to associate with a dog. In the create action, we’re confirming that the new dog instance is valid, and if it is, creating and redirecting to the new instance’s show rendering (via the dog_path for that dog instance). If the new dog instance is not valid, it saves the associated errors into flash and reloads the form to create a new dog instance.

#app/controllers/dogs_controller.rb1  class DogsController < ApplicationController
2 def new
3 @dog =
4 @breeds = Breed.all
5 end
7 def create
8 @dog = Dog.create(dog_params)
9 if @dog.valid?
10 redirect_to dog_path(@dog)
11 else
12 flash[:errors] = @dog.errors.full_messages
13 redirect_to new_dog_path
14 end
15 end
17 private
19 def dog_params
20 params.require(:dog).permit(:name, :age, :breed_id)
21 end
23 end

Here in our new.erb view, we are here confirming that there is data saved within flash[:errors], and then iterating through each of the errors (as many as exist — see lines 2–4) and then printing them to the page (line 3).

Next, we’re simply creating a form with the form_for helper so the client can create a new dog: a name, an age, and a breed from the Breed model. Here, we can see a collection_select method that is allowing us to create a dropdown so the client can select one of the available breeds.

In the event that the client creates a dog that cannot be validated, the errors that are created will be rendered in the new view for only the next full-page reload. In this case, our create controller reloads the page when the dog instance is not valid.

#views/dogs/new.erb 1  <% if !!flash[:errors] %>
2 <% flash[:errors].each do |e| %>
3 <p><%= e %></p> <br>
4 <% end %>
5 <% end %>
7 <%= form_for @dog do |f| %>
8 <%= f.label :name %>:
9 <%= f.text_field :name %><br>
10 <%= f.label :age %>:
11 <%= f.number_field :age %><br>
12 <%= f.collection_select :breed_id, @breeds, :id, :name %>
13 <%= f.submit %>
14 <% end %>

Now that you’ve seen flash in the wild, you can utilize flash for your own apps and display temporary flashed data to your clients. Further resources about flash are included below for your edification.

Good luck out there, and happy coding!


Stack Overflow: Flash Hash

Stack Overflow: Flash Types

Stack Overflow: The Difference Between Flash:Alert and Flash:Notice

The Pug Automatic (Other Implementation of Flash)

Wikipedia: Stateless Protocol

Github: Rack-Flash

Current Tech Geek | Previous Book Nerd | Always Doggo Lifestyle

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store