class ActiveModel::Validator
Active Model Validator
A simple base class that can be used along with 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[:base] = "This record is invalid"
    end
  end
  private
    def some_complex_logic
      # ...
    end
end
 Any class that inherits from ActiveModel::Validator must implement a method called validate which accepts a 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
 To cause a validation error, you must add to the record's errors directly from within the validators message.
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
 To add behavior to the initialize method, use the following signature:
class MyValidator < ActiveModel::Validator
  def initialize(options)
    super
    @my_custom_field = options[:field_name] || :first_name
  end
end
 Note that the validator is initialized only once for the whole application life cycle, and not on each validation run.
The easiest way to add custom validators for validating individual attributes is with the convenient 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
 This can now be used in combination with the validates method (see ActiveModel::Validations::ClassMethods.validates for more on this).
class Person include ActiveModel::Validations attr_accessor :title validates :title, presence: true, title: true end
It can be useful to access the class that is using that validator when there are prerequisites such as an attr_accessor being present. This class is accessible via +options+ in the constructor. To setup your validator override the constructor.
class MyValidator < ActiveModel::Validator
  def initialize(options={})
    super
    options[:class].send :attr_accessor, :custom_attribute
  end
end
 Attributes
Public Class Methods
# File activemodel/lib/active_model/validator.rb, line 102
def self.kind
  @kind ||= name.split('::').last.underscore.sub(/_validator$/, '').to_sym unless anonymous?
end Returns the kind of the validator.
PresenceValidator.kind # => :presence UniquenessValidator.kind # => :uniqueness
# File activemodel/lib/active_model/validator.rb, line 107
def initialize(options = {})
  @options  = options.except(:class).freeze
end Accepts options that will be made available through the options reader.
Public Instance Methods
# File activemodel/lib/active_model/validator.rb, line 115 def kind self.class.kind end
Returns the kind for this validator.
PresenceValidator.new.kind # => :presence UniquenessValidator.new.kind # => :uniqueness
# File activemodel/lib/active_model/validator.rb, line 121 def validate(record) raise NotImplementedError, "Subclasses must implement a validate(record) method." end
Override this method in subclasses with validation logic, adding errors to the records errors array where necessary.
    © 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.