How to Implement Custom ActiveRecord Validations — Ruby On Rails
Tags: ruby, rails, validations, codequality
Published: 2022-08-10 05:13:00

Ruby on Rails has amazing [docs on validations](https://guides.rubyonrails.org/active_record_validations.html). In this blog post, I want to cover custom validations but will also introduce the standard Active Record validations that Rails give us.

 1. ActiveRecord validations

 2. Custom Validations:
 **■** as methods
 **■** as a separate class

## Active Record validations

Rails provide a variety of helpers out of the box for quickly performing commonly used validations — presence, numerically, uniqueness, etc. If the model has validations that go beyond the standard helpers, we must implement a custom validation strategy. Take for instance this method that checks whether an instance we are trying to create has all the attributes needed:
{% gist https://gist.github.com/kananinirav/c136dbdab788803f16fc00ca4bd64009.js %}
If you require that `name` is unique, of a particular length, contains (or does not) certain characters, etc. then you can with default validations. **They even have an email validation that uses regex**. You can also specify the message that will come if any of the validations is violated.

## Custom validations: methods

Now, what would happen if what you want to validate is not covered by the Rails. If You Want to Validate an **Email using your custom regular expression.**

When you want to implement custom validations, you’ll use `validate` instead of `validates` and add the method name that you declare below it. Here's a user class with validations and pseudocoded method — note that I made the custom validation a private method:
{% gist https://gist.github.com/kananinirav/74e2a244225ba5250d8cc9ceb3789c2e.js %}
## Custom validations: classes

If You want to use similar custom validation in other models then creating class validation is the best option. Define validation one’s and use it in any models. Using this we can create our own custom validations manager according to business requirements.

## 1. New folder, new file, a new class

For the organizational purposes, create a new folder in your `app` folder: `app\validators`. Inside, create a new file, the name of which should describe what this code does. I named mine `email_validator.rb`. Now, inside write a class that inherits from `ActiveModel::EachValidator`:

    class EmailValidator < ActiveModel::EachValidator
    end

## 2. Use the validation in the model

Now, I will use this validator in the User model:

    class User < ApplicationRecord
      validates :email, email: true
    end

## 3. Write out the Validation method

We can finally write our method. Here we will use the `value` parameter to check the email:
{% gist https://gist.github.com/kananinirav/028c5dcef78aa24326b4c711dee3e3e7.js %}
What happens if the email is wrong? Such a situation should result in an error. For that, let’s use the ActiveRecord Error method [add](https://api.rubyonrails.org/classes/ActiveModel/Errors.html#method-i-add). This method accepts three arguments:

* `attribute`, which specifies what the scope of the error should be — it can be either the attribute itself or `:base`, which would just add an error to the whole record;

* `message`, is the message that will be shown for violating this validation; if the message is non-existent, it will just default to "is invalid"; the message can either be a symbol or a hash — in a majority of cases it's going to be a symbol with :invalidkey to having the message display nicely.

And this is the error we will get now:

`ActiveRecord::RecordInvalid (Validation failed: Email Please Enter Valid Email)`

Now our validator can be used across different classes.

If this guide has been helpful to you and your team please share it with others!