DEV Community

Hannah Glazier
Hannah Glazier

Posted on

Rails Validators - A Quick Guide and Cheatsheet

In the complex world of Rails, what exactly are validations and how can we use them? In this blog, I will give an overview of Rails validators and list some common and useful examples. The Rails Guides state that, "validations are used to ensure that only valid data is saved into your database." As a silly analogy, you can consider validations to be the backend's bouncer, making sure all data is dressed appropriately before entering club database. "Model-level validations are the best way to ensure that only valid data is saved into your database." Client-side validations are possible, but can be insecure or inefficient when used alone. Backend validations ensure that your database is only receiving safe and appropriate data.

What Triggers a Validation?

Validations are implemented when any type of change is made to the database. You will run into this most often when you .save or .create, but you can also manually trigger a validation with .valid? or .invalid?. There is also a built in validation method on: that allows you to determine when the validation is triggered:

class User < ApplicationRecord
  validates :age, numericality: true, on: :update
end
Enter fullscreen mode Exit fullscreen mode

Common Built-in Validation Methods

Active Record has numerous built-in validation methods that can be employed for common validation needs. Every time these validations fail, they will trigger an error which you can decide to handle in your own way (more on that later). One of the most common built-in validators is presence: which checks that a certain value has been entered/exists.

class User < ApplicationRecord
  validates :username, presence: true
end
Enter fullscreen mode Exit fullscreen mode

*Note that attributes can also be chained together if the same type of validation needs to be provided for each one:

class User < ApplicationRecord
  validates :username, :birthday, :full_name, presence: true
end
Enter fullscreen mode Exit fullscreen mode

presence: is best used when you do not have any other validations in place. If you have another validation in place for the same attribute, presence: becomes implicit and is not required.

Another common built-in validation is length:, which checks various length constraints:

class User < ApplicationRecord
  validates :name, length: { minimum: 2 }
  validates :bio, length: { maximum: 500 }
  validates :password, length: { in: 6..20 }
  validates :drivers_license, length: { is: 9 }
end
Enter fullscreen mode Exit fullscreen mode

The length: validator can be used against numerous different constraints such as maximum, minimum, an exact length, or a range.

numericality: is used to validate an attribute's numeric value.

class User < ApplicationRecord
  validates :birthday, numericality: true
  validates :phone_number, numericality: { only_integer: true }
end
Enter fullscreen mode Exit fullscreen mode

There are a multitude of numericality: constraints including: :greater_than, :greater_than_or_equal_to, :equal_to, :less_than, :less_than_or_equal_to, :other_than, :in(specifies range), :odd, :even. These validators can be used for a wide range of purposes and are intuitively named for ease of use.

inclusion: is another helpful validator that can ensure that a certain value is included. This can be useful if a user is offered a list of options to choose from, and needs to be constrained to that list.

class User < ApplicationRecord
  validates :eye_color, inclusion: ["brown", "blue", "hazel", "green", "grey"]
end
Enter fullscreen mode Exit fullscreen mode

Another very common validator is uniqueness:, this is important for ensure that data, such as usernames or emails are completely unique to a specific user.

class User < ApplicationRecord
  validates :username, uniqueness: true
end
Enter fullscreen mode Exit fullscreen mode

Some interesting validations are :allow_blank and :allow_nil, these validations are used in a way that bypasses the built-in presence: true so that if information is entered it can be validated, but it can also be left blank or nil.

class User < ApplicationRecord
  validates :bio, length: { minimum: 250 }, allow_blank: true
end
Enter fullscreen mode Exit fullscreen mode

You can also implement conditional validations that are only triggered if a certain condition is met.

class Order < ApplicationRecord
  validates :card_number, presence: true, if: :paid_with_card?

  def paid_with_card?
    payment_type == "card"
  end
end
Enter fullscreen mode Exit fullscreen mode

It is also possible to contain your validations within a certain scope.

class Gate < ApplicationRecord
  validates :gate_num, uniqueness: { scope: :terminal }
end
Enter fullscreen mode Exit fullscreen mode

Custom Validations

Listed above are just a few of the many built in Active Record validation methods, however, when these aren't enough we also have the ability to build our own custom validations. The syntax is as follows:

class CustomValidator < ActiveModel::Validator
  def validate(record)
    unless record.species == 'dog' 
      record.errors.add :species, "Dogs only!"
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

A common syntax gotcha with custom validations is that custom validations use validate rather than validates. When you combine your own custom validations with the myriad of built-in methods, your validating possibilities are nearly endless!

Error Handling

The way you want to handle the errors is a larger topic beyond the scope of this blog as Rails provides you with multiple options, however, I would like to highlight the built-in message: method as it is incorporated directly into your validations.

class User < ApplicationRecord
  validates :username, presence: { message: "must be given please" }
end
Enter fullscreen mode Exit fullscreen mode

Conclusion

Rails validations are a simple and effective way to ensure you are allowing appropriate and safe data into your database. You can choose from numerous built-in validator methods for your most common validation needs or you can use your creative freedom and design custom validations for unique needs.

-Sources-

Ruby on Rails Guides

Top comments (0)