class ActiveModel::Validator
Валидатор Active Model
Простой базовый класс, который можно использовать вместе с ActiveModel::Validations::ClassMethods.validates_with.
class Person
include ActiveModel::Validations
validates_with MyValidator
end
class MyValidator < ActiveModel::Validator
def validate(record)
if some_complex_logic
record.errors.add(:base, "This record is invalid")
end
end
private
def some_complex_logic
# ...
end
end
Любой класс, унаследованный от ActiveModel::Validator, должен реализовать метод с именем validate, который принимает record.
class Person
include ActiveModel::Validations
validates_with MyValidator
end
class MyValidator < ActiveModel::Validator
def validate(record)
record # => The person instance being validated
options # => Any non-standard options passed to validates_with
end
end
Чтобы вызвать ошибку валидации, необходимо добавить ее в массив ошибок record напрямую из сообщения валидатора.
class MyValidator < ActiveModel::Validator
def validate(record)
record.errors.add :base, "This is some custom error message"
record.errors.add :first_name, "This is some complex validation"
# etc...
end
end
Чтобы добавить поведение в метод инициализации, используйте следующий синтаксис:
class MyValidator < ActiveModel::Validator
def initialize(options)
super
@my_custom_field = options[:field_name] || :first_name
end
end
Обратите внимание, что валидатор инициализируется только один раз на протяжении всего жизненного цикла приложения, а не при каждой проверке валидации.
Самый простой способ добавить пользовательские валидаторы для проверки отдельных атрибутов — использовать удобный метод ActiveModel::EachValidator.
class TitleValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
record.errors.add attribute, 'must be Mr., Mrs., or Dr.' unless %w(Mr. Mrs. Dr.).include?(value)
end
end
Теперь это можно использовать в сочетании с методом validates (см. ActiveModel::Validations::ClassMethods.validates для получения более подробной информации об этом).
class Person include ActiveModel::Validations attr_accessor :title validates :title, presence: true, title: true end
Может быть полезно получить доступ к классу, использующему этот валидатор, если есть предварительные условия, такие как наличие attr_accessor. Этот класс доступен через options[:class] в конструкторе. Чтобы настроить свой валидатор, переопределите конструктор.
class MyValidator < ActiveModel::Validator
def initialize(options={})
super
options[:class].attr_accessor :custom_attribute
end
end
Атрибуты
Публичные методы класса
# File activemodel/lib/active_model/validator.rb, line 103
def self.kind
@kind ||= name.split("::").last.underscore.chomp("_validator").to_sym unless anonymous?
end Возвращает тип валидатора.
PresenceValidator.kind # => :presence AcceptanceValidator.kind # => :acceptance
# File activemodel/lib/active_model/validator.rb, line 108
def initialize(options = {})
@options = options.except(:class).freeze
end Принимает параметры, которые будут доступны через метод получения options.
Публичные методы экземпляра
# File activemodel/lib/active_model/validator.rb, line 116 def kind self.class.kind end
Возвращает тип валидатора.
PresenceValidator.new(attributes: [:username]).kind # => :presence AcceptanceValidator.new(attributes: [:terms]).kind # => :acceptance
# File activemodel/lib/active_model/validator.rb, line 122 def validate(record) raise NotImplementedError, "Subclasses must implement a validate(record) method." end
Переопределите этот метод в подклассах для логики валидации, добавляя ошибки в массив errors записей при необходимости.
© 2004–2020 David Heinemeier Hansson
Licensed under the MIT License.