Validation errors in Ruby on Rails

We’ll look at validation errors in more detail in the Dealing with Validation Errors section.

errors.details

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

classPerson < ApplicationRecord

  validates :name, presence: true

end

>>person = Person.new

>> person.valid?

>> person.errors.details[:name] # => [{error: :blank}]

Using details with your own validator is covered in Dealing with Validation Errors.

Validation helpers

Active Record offers many predefined validation helpers that you can use right inside your class definitions. These helpers provide general validation rules. Each time the validation fails, an error message is added to the object’s errors collection, and the message is associated with the attribute that was to be validated.

Each helper accepts an arbitrary number of attribute names, so you can add validations of the same kind to multiple attributes in one line of code.

They all take :on and :message options that specify when the validation should be run and what message should be added to the errors collection if it fails. The :on option takes one of the values ​​:create or :update. Each validation helper has its own default error message. These messages are used if the :message option is not specified. Let’s take a look at each of the available helpers.

acceptance

This method checks that a checkbox in the user interface was clicked when the form was submitted. Typically used when the user needs to agree to your app’s terms of use, confirm that some text has been read, or some other similar concept.

classPerson < ApplicationRecord

  validates :terms_of_service, acceptance: true

end

This check will only be executed if terms_of_service is not nil. For this helper, the default error message is “must be accepted”. You can send an arbitrary message using the message option.

classPerson < ApplicationRecord

  validates :terms_of_service, acceptance: { message: ‘must be accepted’ }

end

It can also receive an :accept option that specifies the allowed values ​​that should be considered accepted. The default is “1”, but you can change it.

classPerson < ApplicationRecord

  validates :eula, acceptance: { accept: [‘TRUE’, ‘accepted’] }

end

This validation is very specific to web applications and its acceptance does not need to be written anywhere in the database. If you don’t have a field for it, the helper will just create a virtual attribute. If the field exists in the database, the accept option must be set to true or else this validation will fail.

validates_associated

This helper can be used when your model has relationships with other models that also need to be validated. When you try to save your object, the valid? method will be called. for each of the related objects.

class Library < ApplicationRecord

  has_many:books

  validates_associated :books

end

This validation works with all types of links.

CAUTION: Don’t use validates_associated on both ends of your associations, they will call each other in an endless loop.

For validates_associated , the default error message is “is invalid”. Note that each related object has its own collection of errors; errors are not added to the calling model.

confirmation

This helper can be used if you have two text fields from which you want to get completely identical content. For example, you want to verify your email address or password. This validation creates a virtual attribute whose name is the name of the field being confirmed, with “_confirmation” appended.

classPerson < ApplicationRecord

  validates :email, confirmation: true

end

In your view template you need to use something like this

<%= text_field :person, :email %>

<%= text_field :person, :email_confirmation %>

This check is only performed if email_confirmation is non-nil. To require confirmation, you need to add another check for the existence of the checked attribute (we will look at presence a bit later):

classPerson < ApplicationRecord

  validates :email, confirmation: true

  validates :email_confirmation, presence: true

end

There is also a :case_sensitive option which is used to determine if the confirmation constraint should be case sensitive. This option defaults to true.

classPerson < ApplicationRecord

  validates :email, confirmation: { case_sensitive: false }

end

The default error message for this helper is “doesn’t match confirmation”.

exclusion

This helper validates that attribute values ​​are not included in the specified set. In fact, this set can be any enumerable object.

The exclusion helper has a :in option that receives a set of values ​​that should not be accepted by the attributes being checked. The :in option has an alias :within which is used for the same purpose. This example uses the :message option to show you how to include an attribute value. See the message documentation for all message argument options.

The default error message value is “is reserved”.

format

This helper validates attribute values ​​by testing them against the specified regular expression, which is specified with the :with option.

class Product < ApplicationRecord

  validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,

    message: “only allows letters” }

end

The default error message value is “is invalid”.

inclusion

This helper validates attribute values ​​for inclusion in the specified set. In fact, this set can be any enumerable object.

class Coffee < ApplicationRecord

  validates :size, inclusion: { in: %w(small medium large),

    message: “%{value} is not a valid size” }

end

The inclusion helper has an :in option that receives a set of values ​​to be accepted. The :in option has an alias :within which is used for the same purpose. The previous example uses the :message option to show you how you can include an attribute value. See the message documentation for all options.

The default error message value for this helper is “is not included in the list”.

length

This helper validates the length of attribute values. It offers a number of options with which you can define length limits in a variety of ways:

classPerson < ApplicationRecord

  validates :name, length: { minimum: 2 }

  validates :bio, length: { maximum: 500 }

  validates :password, length: { in: 6..20 }

  validates :registration_number, length: { is: 6 }

end

The possible options for limiting the length are:

:minimum – attribute cannot be less than a certain length.

:maximum – attribute cannot be more than a certain length.

:in (or :within) – attribute length must be within the specified range. The value of this option must be an interval.

:is – attribute length must be equal to the specified value.

The meaning of the default error message depends on the type of length validation being performed. It is possible to override these messages by using the :wrong_length, :too_long and :too_short options, and %{count} as the place to insert a number corresponding to the length of the limit being used. You can use the :message option to specify the error message.

classPerson < ApplicationRecord

  validates :bio, length: { maximum: 1000,

    too_long: “%{count} characters is the maximum allowed” }

end

Note that the default error messages are plural (ie, “is too short (minimum is %{count} characters)”). For this reason, when :minimum is 1, you should provide your own message or use presence: true instead. When :in or :within have a lower bound of 1, either provide a custom message or call presence before length.