Validations keep invalid data out of your database. This lesson covers Rails' built-in validations, how to test them, and how to show helpful error messages in your forms.
Important
Work on this lesson in
teachermode.
Learning goals
- You can validate records with Rails' built-in validations and know where to look up the rest.
- You can explain when validations run, how saving behaves on an invalid record, and how to inspect the reasons.
- You can write a custom validation for a rule that spans several attributes.
- You can test a single validation in isolation, e.g. with Shoulda matchers.
- You can show validation errors next to the fields they belong to, styled so the invalid field stands out.
- You can give feedback after a form was saved or rejected, e.g. with flash messages.
Resources
Read what's new to you, skim what's familiar, skip what you already master. Stop when you can meet the learning goals.
Your agent can also generate an overview, a tutorial or an explanation for anything here, tailored to what you already know. Just ask.
- π Rails Guides:
Active Record Validations
Show archive.org snapshot
β the built-in validations,
custom validation methods
Show archive.org snapshot
,
working with
errorsShow archive.org snapshot , displaying errors in views Show archive.org snapshot and thefield_with_errorswrapper Show archive.org snapshot - π Testing ActiveRecord validations with RSpec β one spec per rule, with plain RSpec or shoulda-matchers
- π shoulda-matchers Show archive.org snapshot β setup (MovieDB doesn't ship it, add the gem) and the ActiveModel matchers reference Show archive.org snapshot
- π Rails Guides:
The Flash
Show archive.org snapshot
β
flashvs.flash.now, rendering it in the layout - π Rails Guides:
Making select boxes with ease
Show archive.org snapshot
β for the film-type
<select>in the last exercise
Exercises
Basic validations
Make the following changes to your MovieDB:
- Make sure your MovieDB models have validations for all required fields.
- Make sure you have specs for all your validations in MovieDB.
- Use Shoulda matchers where you think they improve the readability your code.
Working with error messages
Understand how to use the
#errors method
Show archive.org snapshot
to inspect the reasons why a record is invalid.
Make the following changes to your MovieDB:
-
There is no longer a full list of error messages at the top of each failed form.
-
When a form could not be saved, only the fields with errors show their respective error messages.
Your forms should be triples of label, input and error message:
Title [_____________________] Title must not be blank Release year [____-5] Release year must be a positive number -
If a field has more than one error, only show the first error.
-
A web app has a lot of fields, and each must be able to display an error message. Make it easy for a form view to display the error message for a given record and field. Remove as much code from the view as possible.
Tip
You will be writing a ton of forms in your career. Showing the error for a given record and attribute should be maximally comfortable for your views β nudge yourself toward a helper with a nice API, like
error_message(@movie, :title). -
Style your form so that when a field is invalid, the label and error message is colored red. In addition, an invalid field control should have a red border.
Tip
Rails adds an extra element around invalid inputs to help with styling. Inspect an invalid field in your browser to see how it works.
-
Add support for a positive and negative flash message Show archive.org snapshot in your application layout. When a form could be saved successfully, show a flash like "Movie saved". When a form is re-rendered due to a validation error, show a flash like "Could not save".
Tip
Unlike
@variablesset by a controller, flash messages persist to the next request. This is to support the case of setting a flash and then redirect.If you have trouble with flash messages appearing longer than they should, you can set them to
flash.nowor clear all flash messages after displaying them by usingflash.clear.
Custom validations
Add the following feature to your MovieBD:
- The release year field of Movies should always be a number. It can also be missing (
nil). - Movies have a film type. This is a string that is either
"black_and_white"or"color". - The default film type is
"color". - In the movie form we can switch between black and white and color movies using a
<select>. - Add a validation that ensures that
release_year >= 1895for black and white movies andrelease_year >= 1917for color movies.
Add tests for your validation. Make sure you have a test for each case.
Hint
- The year rule spans two attributes β write a custom validation method Show archive.org snapshot instead of bending a built-in validation into shape.
- For the
<select>, see Making select boxes with ease Show archive.org snapshot in the Form Helpers guide.