module ActiveModel::Validations::ClassMethods

def _parse_validates_options(options) #:nodoc:

:nodoc:
def _parse_validates_options(options) #:nodoc:
  case options
  when TrueClass
    {}
  when Hash
    options
  when Regexp
    { :with => options }
  when Range, Array
    { :in => options }
  else
    raise ArgumentError, "#{options.inspect} is an invalid option. Expecting true, Hash, Regexp, Range, or Array"
  end
end

def attribute_method?(attribute)

Check if method is an attribute method or not.
def attribute_method?(attribute)
  method_defined?(attribute)
end

def inherited(base)

Copy validators on inheritance.
def inherited(base)
  dup = _validators.dup
  base._validators = dup.each { |k, v| dup[k] = v.dup }
  super
end

def validate(*args, &block)


end
end
errors.add(:base, ("Must be friends to leave a comment") unless commenter.friend_of?(commentee)
def must_be_friends

end
comment.must_be_friends
validate do |comment|

include ActiveModel::Validations
class Comment

Or with a block which is passed with the current record to be validated:

end
end
errors.add(:base, "Must be friends to leave a comment") unless commenter.friend_of?(commentee)
def must_be_friends

validate :must_be_friends

include ActiveModel::Validations
class Comment

This can be done with a symbol pointing to a method:

you're looking for more descriptive declaration of your validations.
overriding the +validate+ instance method becomes too unwieldy and
Adds a validation method or block to the class. This is useful when
def validate(*args, &block)
  options = args.extract_options!
  if options.key?(:on)
    options = options.dup
    options[:if] = Array.wrap(options[:if])
    options[:if] << "validation_context == :#{options[:on]}"
  end
  args << options
  set_callback(:validate, *args, &block)
end

def validates(*attributes)


validates :password, :presence => true, :confirmation => true, :if => :password_required?

Or to all at the same time:

validates :password, :presence => { :if => :password_required? }, :confirmation => true

to one specific validator:
Finally, the options :if, :unless, :on, :allow_blank and :allow_nil can be given

validates :password, :length => 6..20
validates :gender, :inclusion => %w(male female)
validates :email, :format => /@/

The validators hash can also handle regular expressions, ranges and arrays:

end
validates :name, :title => true

end
end
record.errors[attribute] << "must start with 'the'" unless value =~ /\Athe/i
def validate_each(record, attribute, value)
class TitleValidator < ActiveModel::EachValidator

include ActiveModel::Validations
class Film

allowing custom modules of validators to be included as needed e.g.
Validator classes may also exist within the class being validated

end
validates :email, :presence => true, :email => true
validates :name, :presence => true, :uniqueness => true, :length => { :maximum => 100 }

attr_accessor :name, :email
include ActiveModel::Validations
class Person

end
end
value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
record.errors[attribute] << (options[:message] || "is not an email") unless
def validate_each(record, attribute, value)
class EmailValidator < ActiveModel::EachValidator

and default validators in one call for a given attribute e.g.
The power of the +validates+ method comes when using custom validators

validates :username, :uniqueness => true
validates :username, :presence => true
validates :age, :numericality => true
validates :first_name, :length => { :maximum => 30 }
validates :age, :inclusion => { :in => 0..9 }
validates :email, :format => { :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create }
validates :username, :exclusion => { :in => %w(admin superuser) }
validates :password, :confirmation => true
validates :terms, :acceptance => true

Examples of using the default rails validators:

custom validator classes in their place such as PresenceValidator.
validators can be overridden inside specific classes by creating
validator classes ending in 'Validator'. Note that Rails default
This method is a shortcut to all default validators and any custom
def validates(*attributes)
  defaults = attributes.extract_options!
  validations = defaults.slice!(:if, :unless, :on, :allow_blank, :allow_nil)
  raise ArgumentError, "You need to supply at least one attribute" if attributes.empty?
  raise ArgumentError, "Attribute names must be symbols" if attributes.any?{ |attribute| !attribute.is_a?(Symbol) }
  raise ArgumentError, "You need to supply at least one validation" if validations.empty?
  defaults.merge!(:attributes => attributes)
  validations.each do |key, options|
    begin
      validator = const_get("#{key.to_s.camelize}Validator")
    rescue NameError
      raise ArgumentError, "Unknown validator: '#{key}'"
    end
    validates_with(validator, defaults.merge(_parse_validates_options(options)))
  end
end

def validates_each(*attr_names, &block)

method, proc or string should return or evaluate to a true or false value.
:unless => Proc.new { |user| user.signup_step <= 2 }). The
not occur (e.g. :unless => :skip_validation, or
* :unless - Specifies a method, proc or string to call to determine if the validation should
proc or string should return or evaluate to a true or false value.
or :if => Proc.new { |user| user.signup_step > 2 }). The method,
if the validation should occur (e.g. :if => :allow_validation,
* :if - Specifies a method, proc or string to call to determine
* :allow_blank - Skip validation if attribute is blank.
* :allow_nil - Skip validation if attribute is +nil+.
:save, other options :create, :update).
* :on - Specifies when this validation is active (default is
Options:

end
end
record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
validates_each :first_name, :last_name do |record, attr, value|

attr_accessor :first_name, :last_name

include ActiveModel::Validations
class Person

Validates each attribute against a block.
def validates_each(*attr_names, &block)
  options = attr_names.extract_options!.symbolize_keys
  validates_with BlockValidator, options.merge(:attributes => attr_names.flatten), &block
end

def validates_with(*args, &block)


end
end
options[:my_custom_key] # => "my custom value"
def validate(record)
class MyValidator < ActiveModel::Validator

end
validates_with MyValidator, :my_custom_key => "my custom value"
include ActiveModel::Validations
class Person

to the class and available as options:
If you pass any additional configuration options, they will be passed

The method, proc or string should return or evaluate to a true or false value.
:unless => Proc.new { |user| user.signup_step <= 2 }).
(e.g. :unless => :skip_validation, or
determine if the validation should not occur
* unless - Specifies a method, proc or string to call to
The method, proc or string should return or evaluate to a true or false value.
or :if => Proc.new { |user| user.signup_step > 2 }).
if the validation should occur (e.g. :if => :allow_validation,
* if - Specifies a method, proc or string to call to determine
(:create or :update
* on - Specifies when this validation is active
Configuration options:

end
validates_with MyValidator, MyOtherValidator, :on => :create
include ActiveModel::Validations
class Person

You may also pass it multiple classes, like so:

end
end
# ...
def some_complex_logic
private

end
end
record.errors[:base] << "This record is invalid"
if some_complex_logic
def validate(record)
class MyValidator < ActiveModel::Validator

end
validates_with MyValidator
include ActiveModel::Validations
class Person

to add errors based on more complex conditions.
Passes the record off to the class or classes specified and allows them
def validates_with(*args, &block)
  options = args.extract_options!
  args.each do |klass|
    validator = klass.new(options, &block)
    validator.setup(self) if validator.respond_to?(:setup)
    if validator.respond_to?(:attributes) && !validator.attributes.empty?
      validator.attributes.each do |attribute|
        _validators[attribute.to_sym] << validator
      end
    else
      _validators[nil] << validator
    end
    validate(validator, options)
  end
end

def validators

+validates_with+ method.
List all validators that are being used to validate the model using
def validators
  _validators.values.flatten.uniq
end

def validators_on(attribute)

List all validators that being used to validate a specific attribute.
def validators_on(attribute)
  _validators[attribute.to_sym]
end