Custom Validators
As an exercise, I created a simple custom validator. I had done this before at work, but I had managed to forget how to do it between then and now. I guess that’s why I need a bit of extra practice :)
So the idea is that, instead of including this ugly regex in the model, you can pull it out (or whatever you are using to validate your attribute) and put it in a separate validator class. It makes the model much simpler and makes it so it is no longer responsible for the logic behind the validation.
If you are using Rails, you would just put PhoneValidator within the validators folder and it will find it without requiring it in the model as I do here.
# person.rb require 'phone_validator' class Person include ActiveModel::Validations validates :phone_number, phone: true attr_accessor :phone_number def initialize(attributes = {}) @phone_number = attributes[:phone_number] end end # phone_validator.rb class PhoneValidator < ActiveModel::EachValidator PHONE_REGEX ||= /^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$/ def validate_each(record, attribute, value) unless value =~ PHONE_REGEX record.errors[attribute] = "invalid phone number formatting" end end end