class ActiveModel::Validator - activemodel-4.2.3 Documentation

# 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

options[R]

### Public Class Methods

kind() click to toggle source

Returns the kind of the validator.

    PresenceValidator.kind   # => :presence
    UniquenessValidator.kind # => :uniqueness

    # File lib/active_model/validator.rb, line 102
    def self.kind
      @kind ||= name.split('::').last.underscore.sub(/_validator$/, '').to_sym unless anonymous?
    end

new(options = {}) click to toggle source

Accepts options that will be made available through the `options` reader.

    # File lib/active_model/validator.rb, line 107
    def initialize(options = {})
      @options  = options.except(:class).freeze
    end

### Public Instance Methods

kind() click to toggle source

Returns the kind for this validator.

    PresenceValidator.new.kind   # => :presence
    UniquenessValidator.new.kind # => :uniqueness

    # File lib/active_model/validator.rb, line 115
    def kind
      self.class.kind
    end

validate(record) click to toggle source

Override this method in subclasses with validation logic, adding errors to the records `errors` array where necessary.

    # File lib/active_model/validator.rb, line 121
    def validate(record)
      raise NotImplementedError, "Subclasses must implement a validate(record) method."
    end