2009-08-09 03:29:34 -04:00
|
|
|
module ActiveModel
|
|
|
|
module Validations
|
2010-05-11 09:36:09 -04:00
|
|
|
module HelperMethods
|
|
|
|
private
|
|
|
|
def _merge_attributes(attr_names)
|
|
|
|
options = attr_names.extract_options!
|
|
|
|
options.merge(:attributes => attr_names.flatten)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-08-09 03:29:34 -04:00
|
|
|
module ClassMethods
|
2010-01-07 12:44:35 -05:00
|
|
|
# Passes the record off to the class or classes specified and allows them
|
|
|
|
# to add errors based on more complex conditions.
|
2009-08-09 03:29:34 -04:00
|
|
|
#
|
2010-01-07 12:44:35 -05:00
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Validations
|
2009-08-09 03:29:34 -04:00
|
|
|
# validates_with MyValidator
|
|
|
|
# end
|
|
|
|
#
|
2010-01-07 12:44:35 -05:00
|
|
|
# class MyValidator < ActiveModel::Validator
|
|
|
|
# def validate(record)
|
2009-08-09 03:29:34 -04:00
|
|
|
# if some_complex_logic
|
|
|
|
# record.errors[:base] << "This record is invalid"
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# private
|
|
|
|
# def some_complex_logic
|
|
|
|
# # ...
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# You may also pass it multiple classes, like so:
|
|
|
|
#
|
2010-01-07 12:44:35 -05:00
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Validations
|
2009-08-09 03:29:34 -04:00
|
|
|
# validates_with MyValidator, MyOtherValidator, :on => :create
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# Configuration options:
|
2010-01-07 12:44:35 -05:00
|
|
|
# * <tt>on</tt> - Specifies when this validation is active
|
|
|
|
# (<tt>:create</tt> or <tt>:update</tt>
|
|
|
|
# * <tt>if</tt> - Specifies a method, proc or string to call to determine
|
|
|
|
# if the validation should occur (e.g. <tt>:if => :allow_validation</tt>,
|
|
|
|
# or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>).
|
2009-08-09 03:29:34 -04:00
|
|
|
# The method, proc or string should return or evaluate to a true or false value.
|
2010-01-07 12:44:35 -05:00
|
|
|
# * <tt>unless</tt> - Specifies a method, proc or string to call to
|
|
|
|
# determine if the validation should not occur
|
|
|
|
# (e.g. <tt>:unless => :skip_validation</tt>, or
|
|
|
|
# <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>).
|
2009-08-09 03:29:34 -04:00
|
|
|
# The method, proc or string should return or evaluate to a true or false value.
|
|
|
|
#
|
2010-01-07 12:44:35 -05:00
|
|
|
# If you pass any additional configuration options, they will be passed
|
|
|
|
# to the class and available as <tt>options</tt>:
|
2009-08-09 03:29:34 -04:00
|
|
|
#
|
2010-01-07 12:44:35 -05:00
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Validations
|
2009-08-09 03:29:34 -04:00
|
|
|
# validates_with MyValidator, :my_custom_key => "my custom value"
|
|
|
|
# end
|
|
|
|
#
|
2010-01-07 12:44:35 -05:00
|
|
|
# class MyValidator < ActiveModel::Validator
|
|
|
|
# def validate(record)
|
2009-08-09 03:29:34 -04:00
|
|
|
# options[:my_custom_key] # => "my custom value"
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
2009-12-22 19:37:19 -05:00
|
|
|
def validates_with(*args, &block)
|
2009-12-22 17:12:21 -05:00
|
|
|
options = args.extract_options!
|
2010-01-07 12:44:35 -05:00
|
|
|
args.each do |klass|
|
|
|
|
validator = klass.new(options, &block)
|
|
|
|
validator.setup(self) if validator.respond_to?(:setup)
|
2010-02-18 10:28:48 -05:00
|
|
|
|
|
|
|
if validator.respond_to?(:attributes) && !validator.attributes.empty?
|
|
|
|
validator.attributes.each do |attribute|
|
|
|
|
_validators[attribute.to_sym] << validator
|
|
|
|
end
|
|
|
|
else
|
|
|
|
_validators[nil] << validator
|
|
|
|
end
|
|
|
|
|
2010-01-07 12:44:35 -05:00
|
|
|
validate(validator, options)
|
|
|
|
end
|
2009-08-09 03:29:34 -04:00
|
|
|
end
|
|
|
|
end
|
2010-05-11 06:28:42 -04:00
|
|
|
|
|
|
|
# Passes the record off to the class or classes specified and allows them
|
|
|
|
# to add errors based on more complex conditions.
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Validations
|
|
|
|
#
|
|
|
|
# validates :instance_validations
|
|
|
|
#
|
|
|
|
# def instance_validations
|
|
|
|
# validates_with MyValidator
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
2010-05-11 09:36:09 -04:00
|
|
|
# Please consult the class method documentation for more information on
|
|
|
|
# creating your own validator.
|
2010-05-11 06:28:42 -04:00
|
|
|
#
|
|
|
|
# You may also pass it multiple classes, like so:
|
|
|
|
#
|
|
|
|
# class Person
|
|
|
|
# include ActiveModel::Validations
|
|
|
|
#
|
|
|
|
# validates :instance_validations, :on => :create
|
|
|
|
#
|
|
|
|
# def instance_validations
|
|
|
|
# validates_with MyValidator, MyOtherValidator
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
# Standard configuration options (:on, :if and :unless), which are
|
|
|
|
# available on the class version of validates_with, should instead be
|
|
|
|
# placed on the <tt>validates</tt> method as these are applied and tested
|
|
|
|
# in the callback
|
|
|
|
#
|
|
|
|
# If you pass any additional configuration options, they will be passed
|
2010-05-11 09:36:09 -04:00
|
|
|
# to the class and available as <tt>options</tt>, please refer to the
|
|
|
|
# class version of this method for more information
|
2010-05-11 06:28:42 -04:00
|
|
|
#
|
|
|
|
def validates_with(*args, &block)
|
|
|
|
options = args.extract_options!
|
|
|
|
args.each do |klass|
|
|
|
|
validator = klass.new(options, &block)
|
|
|
|
validator.validate(self)
|
|
|
|
end
|
|
|
|
end
|
2009-08-09 03:29:34 -04:00
|
|
|
end
|
2010-01-07 12:44:35 -05:00
|
|
|
end
|