Comparison Validator in Rails 7
Tags: rails, activerecordvalidators, ruby
Published: 2022-09-01 11:00:40

Comparison with another **value**, **proc**, or **attribute**.

ActiveRecord Validations are the most widely used and well-known functionality in Rails. It provides a complete validation framework to validate the state of an object before it is saved in the database. There are various ActiveRecord Validators like `presence` , `uniqueness` , `length` and so on…

If you had a scenario of validating an attribute with some value, in the older versions of Rails we had to write our own custom validations for the same. However, Rails 7 has now added `ComparisonValidtor`. This provides us with an easy way to validate a comparison between two comparable values. This validator requires an option[`value`, `proc`, or `symbol`] to be supplied for comparing.

![Comparison](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dljzwz7rif8pz6s32h72.png)

Let's assume we have a model appointment where we have attributes `start_date` and `end_date` along with others.

**Before**
If you had to validate `end_date` attribute for any provided value or another attribute, we had to write the custom validation as shown below:

```
class Appointment < ApplicationRecord
  
  validates :start_date, presence: true
  validates :end_date, presence: true
  validate :end_date_is_after_start_date
  def end_date_is_after_start_date
    if end_date < start_date
      errors.add(:end_date, 'can not be before the start 
                 date')
    end
  end
end
```
**With Rails 7**
You don't need to use any custom validation and the ComparisonValidtor comes to the rescue. Let's rewrite using the comparison

```
class Appointment < ApplicationRecord
  validates :start_date, presence: true
  validates :end_date, presence: true
  validates :end_date, comparison: { greater_than: :start_date }
  # OR
  validates_comparison_of :end_date, greater_than: :start_date
end

```

ComparisonValidator provides support to the below-mentioned options:

- `greater_than` : Specifies that the value must be greater than the supplied value. The default error message would be “must be greater than %{value}”.

- `greater_than_or_equal_to` : Specifies that the value must be greater or equal to the supplied value. The default error message is “must be greater than or equal to %{value}”.

- `equals_to` : Specifies that the value should be equal to the supplied value.

- `less_than` : Specifies that the value should be less than the supplied value.

- `less_than_or_equal_to` : This signifies that the value should be less than or equal to the supplied value.

- `other_than` : Specifies that the value must be other than the supplied value. The default error message is “must be other than the %{value}”

**Can we combine multiple Compare options?**
Yes, absolutely! We can combine multiple compare options.

Let's say that the end_date must be greater than the start_date and also, wants to validate that the end_date is not today.

```
class Appointment < ApplicationRecord
  validates :start_date, presence: true
  validates :end_date, presence: true
  validates_comparison_of :end_date, greater_than: 
   :start_date, other_than: Date.today
end
```
**Is ComparisonValidator only for date comparison?**
Absolutely no, we can compare `numeric` , `date` and as well as the `string` values with the ComparisonValidator.

```
class Author < ApplicationRecord
   validates_comparison_of :books_count, greater_than: 5
end
```
ComparisonValidator is definitely a great addition to Rails 7. As it allows us to compare the data without being to write the custom validations and validates the data effortlessly.

Happy Coding!!❤️