Skip to content
This repository
tag: v3.1.0.rc4
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 143 lines (137 sloc) 4.77 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
module ActiveModel
  module Validations
    module HelperMethods
      private
        def _merge_attributes(attr_names)
          options = attr_names.extract_options!
          options.merge(:attributes => attr_names.flatten)
        end
    end

    class WithValidator < EachValidator
      def validate_each(record, attr, val)
        method_name = options[:with]

        if record.method(method_name).arity == 0
          record.send method_name
        else
          record.send method_name, attr
        end
      end
    end

    module ClassMethods
      # 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_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
      #
      # You may also pass it multiple classes, like so:
      #
      # class Person
      # include ActiveModel::Validations
      # validates_with MyValidator, MyOtherValidator, :on => :create
      # end
      #
      # Configuration options:
      # * <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>).
      # The method, proc or string should return or evaluate to a true or false value.
      # * <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>).
      # The method, proc or string should return or evaluate to a true or false value.
      #
      # If you pass any additional configuration options, they will be passed
      # to the class and available as <tt>options</tt>:
      #
      # class Person
      # include ActiveModel::Validations
      # validates_with MyValidator, :my_custom_key => "my custom value"
      # end
      #
      # class MyValidator < ActiveModel::Validator
      # def validate(record)
      # options[:my_custom_key] # => "my custom value"
      # end
      # end
      #
      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
    end

    # 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
    #
    # Please consult the class method documentation for more information on
    # creating your own validator.
    #
    # 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
    # to the class and available as <tt>options</tt>, please refer to the
    # class version of this method for more information
    #
    def validates_with(*args, &block)
      options = args.extract_options!
      args.each do |klass|
        validator = klass.new(options, &block)
        validator.validate(self)
      end
    end
  end
end
Something went wrong with that request. Please try again.