I have two classes responsible for attributes validation:
class NameValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
message = options.fetch(:message, I18n.t('errors.attributes.name.invalid'))
record.errors[attribute] << message unless NameValidator.valid_name?(value)
end
def self.valid_name?(name)
name =~ /\A[a-z][\w\p{Blank}]+\z/i
end
end
and the second one
class EmailValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
message = options.fetch(:message, I18n.t('errors.attributes.email.invalid'))
record.errors[attribute] << message unless EmailValidator.valid_email?(value)
end
def self.valid_email?(email)
email =~ /\A.+@.+\..+\z/i
end
end
They're basically the same. Should I inherit them from one class with protected utility methods or what?
You can simplify this further
class PatternValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
message = options.fetch(:message) || kind
record.errors[attribute] << message unless value =~ validation_pattern
end
end
class NameValidator < PatternValidator
def validation_pattern; /\A[a-z][\w\p{Blank}]+\z/i end
end
class EmailValidator < PatternValidator
def validation_pattern; /\A.+@.+\..+\z/i end
end
EachValidator has a #kind method so it will add :name or :email as the failure message unless overridden. Then you can leave the i18n to do the lookup as per the standard cascade as documented in rails guide.