Leissan
Posted on April 1, 2023
Why are data validations important? We perform validations in order to ensure that only valid data is saved into our database. It may seem as if data validation is a step that slows down our pace of work, however, it is an essential ingredient to our workflow rather than an additional step.
We are doing so many important things online, like open bank accounts, sign into our student portals, check our flight status, etc., all of which are powered by data. And data validations are the most effective way to ensure data quality and integrity.
As we know, Ruby on Rails is structured on the MVC architecture. The "M", also called the model layer, is responsible for managing how objects are created and stored in a database. In Rails, the model layer is run by Active Record by default, and as such, Active Record is responsible for handling the important task of data validation. Model-level validations protect our database, because they ensure that only valid data is saved there.
What are some of the types of validations we can perform with Active Record? There are some validations that come packaged with Active Record, and there are custom validations, that we can build ourselves.
Build-in Active Record Validations
First of all, it’s important to know that not all methods trigger validation!
The ones that trigger validation are:
• create
• create!
• save
• save!
• update
• update!
These ones do NOT trigger validation:
• decrement!
• decrement_counter
• increment!
• increment_counter
• insert
• insert!
• insert_all
• insert_all!
• toggle!
• touch
• touch_all
• update_all
• update_attribute
• update_column
• update_columns
• update_counters
• upsert
• upsert_all
There are numerous validation helpers we can use to validate different aspects of our data. We can use valid? to trigger our validations and to return true if no errors were found in the object, and false otherwise. Let’s run through some examples.
One of the most common situations we all have come across is to have a mandatory piece of data when we are filling out a form. For example, we want to make sure the user definitely inputs their username in some form. This is how we would make sure that they do:
Here we used a helper “presence” which – you guessed it! – ensures that a specific attribute is filled out. Easy and effective!
What is we want to go a step further and make sure that not only they filled out their username, but that it is also unique? Here comes another helper, uniqueness:
If there is anything wrong with our data, there is a list of error messages saved when .valid? returns false. We can see these error messages through using the .error.messages method. We can also use .invalid?, which is the reverse of the .valid? method. Let’s see that in action:
Errors.messages are extremely important, because they will tell us exactly what went wrong with our data. We can also check each attribute for errors separately, passing it as a key:
There are a couple of important moments here. First of all, we can see that the validation does not trigger until we try to use a method which triggers validation, in this case – save. There is no error message before we save! Secondly, we can see a specific error message related to an attribute we want to check, :username, by running u.errors[:username].
You can access a full list of validation helpers on Rails Guides.
Custom Validations
We don’t have to limit ourselves to pre-built validations (although they are very useful!). Active Record gives us several easy ways to build custom validations, the most straight forward of which is to use a custom method to perform a validation. Let’s say we are building a website for travelers, and we want to make sure their favorite destination includes Brazil:
A couple of key moments here: with custom validation, we are using the method “validate”, not “validates”, and then we are passing it a method that we define ourselves below. We also specify our custom error, should the user not follow our fave_destination rule.
Speaking of errors, ideally we want our controller to tell us if, for example, our user data was saved successfully, and if not, tell us exactly why not. How would we do it with built-in validations? Below we are updating our controller action to provide is a specific response if the user was not saved successfully:
And there we have it - we just learned the best ways to ensure our data integrity using Active Record!
Posted on April 1, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.