Используйте наследование только тогда, когда один класс явно является особым случаем другого. В вашем примере, кажется, что два класса равны. Затем используйте mixin, а не наследование.
Небольшой пункт в вашем коде, который стоит против общего использования validate_each
является жестким кодом NameValidator.valid_name?
и EmailValidator.valid_email?
. Вы должны сделать их одинаковыми в общем коде, который будет использоваться в обоих классах. Прежде всего, вам не нужно указывать разные имена valid_name?
и valid_email?
. Их различия должны быть поглощены использованием соответствующих классов. Используйте общее имя. Во-вторых, вам не нужно жестко закодировать приемник. Вместо этого используйте self.class
. Но вместо того, чтобы делать это с помощью методов класса, используйте метод экземпляра.
module ValidatorModule
def validate_each(record, attribute, value)
message = options.fetch(:message, I18n.t("errors.attributes.#{attribute}.invalid"))
record.errors[attribute] << message unless valid?(value)
end
end
class NameValidator < ActiveModel::EachValidator
include ValidatorModule
def attribute; "name" end
def valid?(value); value =~ /\A[a-z][\w\p{Blank}]+\z/i end
end
class EmailValidator < ActiveModel::EachValidator
include ValidatorModule
def attribute; "email" end
def valid?(value); value =~ /\[email protected]+\..+\z/i end
end
Если вы считаете, что проверка всегда делается с помощью одного регулярного выражения, вы можете пойти один шаг дальше:
module ValidatorModule
def validate_each(record, attribute, value)
message = options.fetch(:message, I18n.t("errors.attributes.#{attribute}.invalid"))
record.errors[attribute] << message unless value =~ validation_pattern
end
end
class NameValidator < ActiveModel::EachValidator
include ValidatorModule
def attribute; "name" end
def validation_pattern; /\A[a-z][\w\p{Blank}]+\z/i end
end
class EmailValidator < ActiveModel::EachValidator
include ValidatorModule
def attribute; "email" end
def validation_pattern; /\[email protected]+\..+\z/i end
end
ИМХО это было бы хорошим вопросом для http://codereview.stackexchange.com/ –