<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,12 +1,10 @@
 module ActiveModel
   module Validations
-    VALIDATIONS = %w( validate validate_on_create validate_on_update )
-
     def self.included(base) # :nodoc:
       base.extend(ClassMethods)
       base.send!(:include, ActiveSupport::Callbacks)
 
-      VALIDATIONS.each do |validation_method|
+      %w( validate validate_on_create validate_on_update ).each do |validation_method|
         base.class_eval &lt;&lt;-&quot;end_eval&quot;
           def self.#{validation_method}(*methods, &amp;block)
             methods = CallbackChain.build(:#{validation_method}, *methods, &amp;block)
@@ -25,16 +23,68 @@ module ActiveModel
       end
     end
 
-    # All of the following validations are defined in the class scope of the model that you're interested in validating.
-    # They offer a more declarative way of specifying when the model is valid and when it is not. It is recommended to use
-    # these over the low-level calls to validate and validate_on_create when possible.
     module ClassMethods
-      DEFAULT_VALIDATION_OPTIONS = {
-        :on          =&gt; :save,
-        :allow_nil   =&gt; false,
-        :allow_blank =&gt; false,
-        :message     =&gt; nil
-      }.freeze
+      DEFAULT_VALIDATION_OPTIONS = { :on =&gt; :save, :allow_nil =&gt; false, :allow_blank =&gt; false, :message =&gt; nil }.freeze
+
+      # Adds a validation method or block to the class. This is useful when
+      # overriding the #validate instance method becomes too unwieldly and
+      # you're looking for more descriptive declaration of your validations.
+      #
+      # This can be done with a symbol pointing to a method:
+      #
+      #   class Comment &lt; ActiveRecord::Base
+      #     validate :must_be_friends
+      #
+      #     def must_be_friends
+      #       errors.add_to_base(&quot;Must be friends to leave a comment&quot;) unless commenter.friend_of?(commentee)
+      #     end
+      #   end
+      #
+      # Or with a block which is passed the current record to be validated:
+      #
+      #   class Comment &lt; ActiveRecord::Base
+      #     validate do |comment|
+      #       comment.must_be_friends
+      #     end
+      #
+      #     def must_be_friends
+      #       errors.add_to_base(&quot;Must be friends to leave a comment&quot;) unless commenter.friend_of?(commentee)
+      #     end
+      #   end
+      #
+      # This usage applies to #validate_on_create and #validate_on_update as well.
+
+      # Validates each attribute against a block.
+      #
+      #   class Person &lt; ActiveRecord::Base
+      #     validates_each :first_name, :last_name do |record, attr, value|
+      #       record.errors.add attr, 'starts with z.' if value[0] == ?z
+      #     end
+      #   end
+      #
+      # Options:
+      # * &lt;tt&gt;on&lt;/tt&gt; - Specifies when this validation is active (default is :save, other options :create, :update)
+      # * &lt;tt&gt;allow_nil&lt;/tt&gt; - Skip validation if attribute is nil.
+      # * &lt;tt&gt;allow_blank&lt;/tt&gt; - Skip validation if attribute is blank.
+      # * &lt;tt&gt;if&lt;/tt&gt; - Specifies a method, proc or string to call to determine if the validation should
+      #   occur (e.g. :if =&gt; :allow_validation, or :if =&gt; Proc.new { |user| user.signup_step &gt; 2 }).  The
+      #   method, proc or string should return or evaluate to a true or false value.
+      # * &lt;tt&gt;unless&lt;/tt&gt; - Specifies a method, proc or string to call to determine if the validation should
+      #   not occur (e.g. :unless =&gt; :skip_validation, or :unless =&gt; Proc.new { |user| user.signup_step &lt;= 2 }).  The
+      #   method, proc or string should return or evaluate to a true or false value.
+      def validates_each(*attrs)
+        options = attrs.extract_options!.symbolize_keys
+        attrs   = attrs.flatten
+
+        # Declare the validation.
+        send(validation_method(options[:on] || :save), options) do |record|
+          attrs.each do |attr|
+            value = record.send(attr)
+            next if (value.nil? &amp;&amp; options[:allow_nil]) || (value.blank? &amp;&amp; options[:allow_blank])
+            yield record, attr, value
+          end
+        end
+      end
 
       private
         def validation_method(on)
@@ -67,7 +117,7 @@ module ActiveModel
 
         if responds_to?(:validate_on_create)
           ActiveSupport::Deprecations.warn(
-            &quot;Base#validate_on_create has been deprecated, please use Base.validate :method, :on =&gt; :create instead&quot;)
+            &quot;Base#validate_on_create has been deprecated, please use Base.validate_on_create :method instead&quot;)
           validate_on_create
         end
       else
@@ -75,7 +125,7 @@ module ActiveModel
 
         if responds_to?(:validate_on_update)
           ActiveSupport::Deprecations.warn(
-            &quot;Base#validate_on_update has been deprecated, please use Base.validate :method, :on =&gt; :update instead&quot;)
+            &quot;Base#validate_on_update has been deprecated, please use Base.validate_on_update :method instead&quot;)
           validate_on_update
         end
       end</diff>
      <filename>activemodel/lib/active_model/validations.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>activemodel/lib/active_model/validations/each.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>de56a4a4de94416309ce05fc19ef9c4c020a042c</id>
    </parent>
  </parents>
  <author>
    <name>david</name>
    <email>david@5ecf4fe2-1ee6-0310-87b1-e25e094e27de</email>
  </author>
  <url>http://github.com/NZKoz/koz-rails/commit/d80f9971b2331e04616864c43a2e9ee49beb5cb6</url>
  <id>d80f9971b2331e04616864c43a2e9ee49beb5cb6</id>
  <committed-date>2008-03-31T17:13:39-07:00</committed-date>
  <authored-date>2008-03-31T17:13:39-07:00</authored-date>
  <message>Move it around a bit

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@9174 5ecf4fe2-1ee6-0310-87b1-e25e094e27de</message>
  <tree>d0bc1c319ea8763ee61c3384e33d36a825733840</tree>
  <committer>
    <name>david</name>
    <email>david@5ecf4fe2-1ee6-0310-87b1-e25e094e27de</email>
  </committer>
</commit>
