Rails: Active Record Validations

What are Validations?

Validations are used to ensure that only valid data is saved into your database. For example, it may be important to your application to ensure that every user provides a valid email address and mailing address. Model-level validations are the best way to ensure that only valid data is saved into your database. They are database agnostic, cannot be bypassed by end users, and are convenient to test and maintain. Rails makes them easy to use, provides built-in helpers for common needs, and allows you to create your own validation methods as well.

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 fresh object, for example using the new method, that object does not belong to the database yet. Once you call save upon 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. Consider the following simple Active Record class:

class Person < ApplicationRecordend

We can see how it works by looking at some rails console output:

$ rails console
>> p = Person.new(name: "John Doe")
=> #<Person id: nil, name: "John Doe", created_at: nil, updated_at: nil>
>> p.new_record?
=> true
>> p.save
=> true
>> p.new_record?
=> false

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 versions (e.g. save!) raise an exception if the record is invalid. The non-bang versions don't: save and update return false , and create just returns the object.

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. As you saw above:

class Person < ApplicationRecord
validates :name, presence: true
end
Person.create(name: "John Doe").valid? # => true
Person.create(name: nil).valid? # => false

After Active Record has performed validations, any errors found can be accessed through the errors.messages instance method, which returns a collection of errors. By definition, an object is valid if this collection is empty after running validations.

class Person < ApplicationRecord
validates :name, presence: true
end
$ rails console
>> p = Person.new
# => #<Person id: nil, name: nil>
>> p.errors.messages
# => {}
>> p.valid?
# => false
>> p.errors.messages
# => {name:["can't be blank"]}
>> p = Person.create
# => #<Person id: nil, name: nil>
>> p.errors.messages
# => {name:["can't be blank"]}
>> p.save
# => false
>> p.save!
# => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
>> Person.create!
# => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank

errors[]

To verify whether or not a particular attribute of an object is valid, you can use errors[:attribute]. It returns an array of all the errors for :attribute. If there are no errors on the specified attribute, an empty array is returned.

This method is only useful after validations have been run, because it only inspects the errors collection and does not trigger validations itself.

class Person < ApplicationRecord
validates :name, presence: true
end
>> Person.new.errors[:name].any?
# => false
>> Person.create.errors[:name].any?
# => true

To check which validations failed on an invalid attribute, you can use errors.details[:attribute]. It returns an array of hashes with an :error key to get the symbol of the validator:

class Person < ApplicationRecord
validates :name, presence: true
end
>> person = Person.new
>> person.valid?
>> person.errors.details[:name] # => [{error: :blank}]

Thank You for reading this blog, also wait for its second part to get complete information about validation. Don’t forget to 👏 if you enjoyed reading it. References: https://guides.rubyonrails.org/active_record_validations.html

--

--