Validators run even if nil

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the rails category.

Last Updated: 2024-11-23

I had the following code to validate emails:

validates :sender_email, email: true
validates_presence_of :sender_email

It used a custom validator, implemented as follows:

class EmailValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    simple_email_regex = /.+@.+\..+/i
    return if value.match(simple_email_regex)

    record.errors.add attribute, 'email looks invalid'
  end
end

What went wrong? Despite the validates_presence_of :sender_email elsewhere in the file, this validator sometimes ran with nil for the value, causing it to crash, on value.match, since nil#match does not exist.

Lesson

Custom validators may run even if you have other code that supposedly checks for non nil-iness. Therefore it is wiser to add guard clauses to protect against nil in your validators.