DEV Community

Cover image for Ruby on Rails ActiveRecord Validations
Eapen Zacharias
Eapen Zacharias

Posted on

Ruby on Rails ActiveRecord Validations

Validations allow us to make sure that data meets a set of requirements before it's saved to the database. You can think of them as rules that our data must follow. It is always a good practice to check the validations from the models to make our models smarter by telling them about what should be considered valid data in the database and also regardless of where we're submitting data from the application, it'll still follow the rules.

Built in Validation Methods

Rails provided many inbuilt validation helpers which covers most use cases when you are building an app. Here are the most important ones:

# validates_presence_of validates the attribute is not blank

validates_presence_of :atrr_name
Enter fullscreen mode Exit fullscreen mode

# Validates_length_of check length requirements of the attribute

validates_length_of :attr_name, :within => 3..40
validates_length_of :attr_name, :is => 40
validates_length_of :attr_name, :minimum => 10, :maximum => 50
Enter fullscreen mode Exit fullscreen mode
  • :minimum - The attribute cannot have less than the specified length.
  • :maximum - The attribute cannot have more than the specified length.
  • :in (or :within) - The attribute length must be included in a given interval. The value for this option must be a range.
  • :is - The attribute length must be equal to the given value.

# Validates_numecality_of check if the attribute is a number or not

validates_numericality_of :height, :greater_than => 3.0
validates_numericality_of :height, :less_than => 100
validates_numericality_of :height, :equal_to => 3.0
validates_numericality_of :height, :greater_than_or_equal_to => 3.0
validates_numericality_of :height, :less_than_or_equal_to => 100
Enter fullscreen mode Exit fullscreen mode
  • :greater_than - Specifies the value must be greater than the supplied value. The default error message for this option is "must be greater than %{count}".
  • :greater_than_or_equal_to - Specifies the value must be greater than or equal to the supplied value. The default error message for this option is "must be greater than or equal to %{count}".
  • :equal_to - Specifies the value must be equal to the supplied value. The default error message for this option is "must be equal to %{count}".
  • :less_than - Specifies the value must be less than the supplied value. The default error message for this option is "must be less than %{count}".
  • :less_than_or_equal_to - Specifies the value must be less than or equal to the supplied value. The default error message for this option is "must be less than or equal to %{count}".
  • :other_than - Specifies the value must be other than the supplied value. The default error message for this option is "must be other than %{count}".
  • :in - Specifies the value must be in the supplied range. The default error message for this option is "must be in %{count}".
  • :odd - Specifies the value must be an odd number if set to true. The default error message for this option is "must be odd".
  • :even - Specifies the value must be an even number if set to true. The default error message for this option is "must be even".

# Validates_inclusion_of checks to see if an attribute is in a list of choices, and you need to provide it an array or a range for it to look in.
# Validates_exclusion_of checks to see if it is not present in the list of choices

validates_inclusion_of :status, :in => ['new', 'created', 'approved', 'deleted']
validates_exclusion_of :status, :in => [55, 66, 77]
Enter fullscreen mode Exit fullscreen mode

# Validates_format_of check if it matches regex

validates_format_of :zipcode, :with => /\d{6}/
Enter fullscreen mode Exit fullscreen mode

# Validates_uniqueness_of is going to make sure that an attribute is not already in the database.

validates_uniqueness_of :user_name, :case_sensitive => false
validates_uniqueness_of :teacher_id, scope: [:semester_id, :class_id]
 # Making sure that a teacher can only be on the schedule once per semester for a particular class.
Enter fullscreen mode Exit fullscreen mode

# Validates_confirmation_of Encapsulates the pattern of wanting to validate a password or email address field with a confirmation


 validates_confirmation_of :user_name, :password
 validates_confirmation_of :email_address,
                              message: 'should match confirmation'
# The added password_confirmation attribute is virtual; it exists only as an in-memory attribute for validating the password. To achieve this, the validation adds accessors to the model for the confirmation attribute.
# NOTE: This check is performed only if password_confirmation is not nil. To require confirmation, make sure to add a presence check for the confirmation attribute:
Enter fullscreen mode Exit fullscreen mode

# Validates_associated is used to check associations with other models, so it check the validity of the associated model

class Library < ApplicationRecord
    has_many :books
    validates_associated :books
end
Enter fullscreen mode Exit fullscreen mode

# Validates_acceptance_of is typically used when the user needs to agree to your application's terms of service, confirm that some text is read, or any similar concept. This method creates a virtual attribute and it is not saved to the database.

validates_acceptance_of :terms_of_service
Enter fullscreen mode Exit fullscreen mode

# Validate multiple parameters in one go

validates :attr_name,
    :presence => boolean,
    :numericality => boolean,
    :length => option_hash,
    :format => {:with => regex},
    :inclusion => {:in => range_or_array},
    :exclusion => {:in => range_or_array},
    :acceptance => boolean,
    :uniqueness => boolean,
    :confirmation => boolean
Enter fullscreen mode Exit fullscreen mode

Custom Validations

Most of the time, the built-in validations that Ruby on Rails gives you, are going to be enough to help you keep your data under control. But every now and then there's some special cases that come up where they're not enough and we'd like to be able to write our own custom validations. Well, Ruby on Rails lets us do that too.

validate :custom_method

private

def custom_method
    if test_case
        error.add(:attribute, "error message")
        # You can use :base as attribute name if the error is not specific to an attribute 
    end
end
Enter fullscreen mode Exit fullscreen mode

Skipping Validation

Skipping validations bypasses the data rules that you've established for the application and it should be done with extreme caution because you could actually introduce invalid data into the database and that could have severe consequences to the application.
Here are few ways to do that.

record.save(validate: false)
record.update_columns(:name => value) # This directly updates the database
record.update_column(:name, value)
Enter fullscreen mode Exit fullscreen mode

When you have an active record relation, you've built up like a relation defined using where clauses to find the record you want, then you can call, update all and provide a hash of values and it will go and do update columns ****on all of those records without actually finding them.

relation.update_all(:name => value)
Enter fullscreen mode Exit fullscreen mode

Thanks For Reading, Follow Me For More
Share your suggestions, doubts and feedback in the comments section!

Top comments (0)