DEV Community

grant-ours
grant-ours

Posted on

Active Record Validations

Overview

What is a Validation?

Here's an example.

class User < ApplicationRecord
  validates :name, presence: true
end
Enter fullscreen mode Exit fullscreen mode
irb> User.create(name: "John Doe").valid?
=> true
irb> User.create(name: nil).valid?
=> false
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)