Validations and Flash in Rails: the Basics
By: Tracie Masek
Tags: Validation, Ruby on Rails, Beginner, Bootcamp

It should come as no surprise that Rails has a bunch of built in methods to help validate data before persisting in our database. Check out the ActiveRecord validation docs to see the full list of options for model-level validations.

For this blog post, we’ll set up a super simple validation in one of our models to check to make sure a user has entered a name when creating a record. We’ll then show how to display validation error messages to the user with flash .

As the phrase “model-level validations” suggests, the validation methods live in the model. Here we’re validating that each employee will be created with a name, and that each name is unique:

#app/models/employee.rb 1 class Employee < ApplicationRecord

2 validates :name, presence: true

3 validates :name, uniqueness: true

4 end

If we have a form in our new view page to create a new employee, this validation method won’t let the data be saved to the database without something unique entered in the name field. However, the validates method in the controller alone won’t tell our user anything. It won’t notify them that their employee was not created, nor will it tell them the reason why.

For that, enter flash ! From the docs:

…flash provides a way to pass temporary primitive-types (String, Array, Hash) between actions. Anything you place in the flash will be exposed to the very next action and then cleared out. This is a great way of doing notices and alerts…

There are a lot of different ways to use flash . For the validation example, we’ll call and set the flash method in our Employee controller’s new action, and then in our new view, we’ll confirm if flash has sent anything and if yes display the message(s) to our user.

In the controller:

#app/controllers/employee_controller.rb 1 def create

2 @employee = Employee.new(employee_params)

3 if @employee.valid?

4 @employee.save

5 redirect_to employee_path(@employee)

6 else

7 flash.now[:messages] = @employee.errors.full_messages[0]

8 render :new

9 end

10 end

If the new instance of the employee we’ve instantiated is valid, great! It’ll get saved to the database. (We could use flash to notify the user that it was successfully created if we wanted.)

However, if any of our validations fail, they will generate error messages that we can then show to our users through flash .

We’ll call the errors and full_messages methods on the instance of the model that we’re trying to create. full_messages returns all the built-in default error messages for each standard validation in an array so we have a couple of options of how to display them to the user.

I like to show the user each message one at a time, so I’ve been assigning the value of flash to the 0 index of the errors.full_messages array. Once the user fixes the error, it won’t appear in the array and flash would then move onto the next error if there are more than one.

In the new view, before the form is rendered, it’ll check to see if flash exists, and if yes, it will display the first error message to the user for the length of one request:

#app/views/employees/new.html.erb 1 <% if flash[:messages] %>

2 <h2><%= flash[:messages] %></h2>

3 <% end %>

You could also leave the [0] off the flash messages that you pass to the view, and choose to iterate over each message in the array in the view and show them all at once.

1 <% if flash[:messages] %>

2 <% flash[:messages].each do |message| %>

3 <h2><%= message%></h2> <br>

4 <% end %>

5 <% end %>

With flash , once the page is reloaded, or another request is made, the message will disappear.

You can create custom error messages AND custom validations. See the docs for instructions.