Long-awaited comparison validator comes to Rails 7

For years we had to manually compare values in our validations. Rails 7 added the comparison validator to ActiveModel. Read on and discover, as we just did, how it works.

Nov 1st, 2023
By Patricio Mac Adden

When dealing with dates, it’s a common practice to compare them to other dates. Take for example a Booking class. A Booking normally has a check-in date and a check-out date. In most cases, when creating a booking, both dates must be in the future. And always, the check-out date must be greater than the check-in date. Otherwise, bookings wouldn’t make sense.

Before Rails 7, these validations didn’t exist and we would have to write a custom validation method, like this:

class Booking < ApplicationRecord
  validates :check_in, presence: true
  validates :check_out, presence: true
  validate :check_out_is_greater_than_check_in

  private

  def check_out_is_greater_than_check_in
    unless check_out.after? check_in
      errors.add :check_out, "can't be before the check in date"
    end
  end
end

Rails 7 introduced the ComparisonValidator to ActiveModel, which simplifies our job greatly. Now, we could do this instead:

class Booking < ApplicationRecord
  validates :check_in, presence: true, comparison: {greater_than: Date.today}
  validates :check_out, presence: true, comparison: {greater_than: :check_in}
end

Today I learned this and I wish this was available a couple of years ago, when the team and I were working on a suite of hospitality apps. Thanks, Ruby on Rails, for existing!