Ruby on Rails Validations

Ruby on Rails / Validations – building custom validator

Ruby on Rails / Validations – building custom validator January 11, 20181 Comment

Sometimes built in validations are not enough so we have to write our own validation rules. Because of this, our models can become fat really quick so the best idea to avoid it is to extract validation logic to separated classes. Such approach makes the code more clean, isolated and reusable.

Model validations

To demonstrate the process of isolating validation code let’s build a sample model class and put there simple validation rule:

class User < ActiveRecord::Base
  PHONE_REGEX = /some_regex/
  validates :phone, format: { with: PHONE_REGEX, message: 'invalid phone number' }

It’s a nice and clean validation rule, however, we can’t reuse it elsewhere. This is the moment when we should consider building validator class. Let’s take a look at the official documentation and find out what they said about it:

The easiest way to add custom validators for validating individual attributes is with the convenient ActiveModel::EachValidator

Custom validator rules

Rules for building custom validator are following:

1. If you want your validator to be automatically loaded you have to use NameValidator name pattern where Name is your validator name and the suffix Validator helps Rails to detect if given class is a validator.
2. Your class should inherit from ActiveModel::EachValidator class
3. You have to implement validate_each method

Custom validator

Let’s stick to the mentioned rules and build our first custom validator:

class PhoneFormatValidator < ActiveModel::EachValidator
  PHONE_REGEX = /some_regex/
  def validate_each(record, attribute, value)
    if value.match(PHONE_REGEX).blank?
      record.errors.add(attribute, 'invalid phone number')

Using custom validator in a Rails model

It’s time to replace our current logic with the custom validator that we build in a previous step. All you have to do is to use the name of your validator:

class User < ActiveRecord::Base
  validates :phone, phone_format: true

Don’t forget to write tests for you validator class!

Having problems with building Ruby on Rails app?

Hit me on twitter or use contact form and let me know how can I help you!

Download free RSpec & TDD ebook

Do you want to earn more or jump to the next level in your company? Do you know that testing skills are one of the most desired skills? There is only first step: start testing and do it right. My ebook can help you. Subscribe to the newsletter to get a free copy of the book.

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *