Overview
What is a Validation?
Here's an example.
class User < ApplicationRecord
validates :name, presence: true
end
irb> User.create(name: "John Doe").valid?
=> true
irb> User.create(name: nil).valid?
=> false
The validation lets us know that our User is not valid without a name attribute. The second User will not be persisted to the database because it did not pass validation.
Why Use Validation?
Validations are used to make sure that only valid data is saved into your database. For example, it may be important in your application to ensure that every user provides a valid username and password. Model-level validations are the best way to ensure that only valid data is saved into your database. Validations cannot be bypassed by end users and are convenient to test and maintain. Rails provides built-in helpers for common needs, and allows you to create your own validation methods as well but I wont be covering all that here.
There are several other ways to validate data before it is saved into your database, including native database constraints, client-side validations and controller-level validations.
When Does Validation Happen?
There are two kinds of Active Record objects: those that correspond to a row inside your database and those that do not. When you create a new object, for example using the new method, that object does not belong to the database yet. Once you call save on that object it will be saved into the appropriate database table. Active Record uses the new_record? instance method to determine whether an object is already in the database or not. In this example we have an Active Record class with no validations:
irb> u = User.new(username: "Johnny")
=> #<User id: nil, username: "Johnny", created_at: nil, updated_at: nil>
irb> u.new_record?
=> true
irb> u.save
=> true
irb> u.new_record?
=> false
Creating and saving a new record will send an SQL INSERT operation to the database. Updating an existing record will send an SQL UPDATE operation instead. Validations are typically run before these commands are sent to the database. If any validations fail, the object will be marked as invalid and Active Record will not perform the INSERT or UPDATE operation. This prevents us from storing an invalid object in the database. You can choose to have specific validations run when an object is created, saved, or updated.
The following methods trigger validations, and will save the object to the database only if the object is valid:
create
create!
save
save!
update
update!
The bang operator ("!") at the end of the method raises an exception if the record is invalid. The non-bang versions don't: save and update return false, and create returns the object.
The following methods skip validations, and will save the object to the database whether it's valid or not. They should be used carefully.
- 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
valid? and invalid?
Before saving an Active Record object, Rails runs your validations. If these validations produce any errors, Rails does not save the object.
You can also run these validations on your own. valid? triggers your validations and returns true if no errors were found in the object, and false otherwise. invalid? is the inverse of valid?. It triggers your validations, returning true if any errors were found in the object, and false otherwise.
There are many helper methods and different ways to deal with and display error messages but I wont delve into those here. Feel free to check them out here https://guides.rubyonrails.org/active_record_validations.html
Top comments (0)