From f296e117c6fb771091a292e4b6d08355801ca3c6 Mon Sep 17 00:00:00 2001
From: David Heinemeier Hansson <david@loudthinking.com>
Date: Thu, 16 Dec 2004 03:23:06 +0000
Subject: Added Base.validates_inclusion_of that validates whether the value of
 the specified attribute is available in a particular enumerable object.
 [what-a-day]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@179 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
---
 activerecord/CHANGELOG                        |  8 ++++++++
 activerecord/lib/active_record/validations.rb | 23 +++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index d80d3a7c86..e7399fb800 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,13 @@
 *CVS*
 
+* Added Base.validates_inclusion_of that validates whether the value of the specified attribute is available in a particular enumerable
+  object. [what-a-day]
+
+    class Person < ActiveRecord::Base
+      validates_inclusion_of :gender, :in=>%w( m f ), :message=>"woah! what are you then!??!!"
+      validates_inclusion_of :age, :in=>0..99
+    end
+
 * Added acts_as_list that can decorates an existing class with methods like move_higher/lower, move_to_top/bottom. [Tobias Luetke] Example:
 
     class TodoItem < ActiveRecord::Base
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index e683721c7a..544754eeb9 100755
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -188,6 +188,28 @@ module ActiveRecord
           class_eval(%(#{validation_method(configuration[:on])} %{errors.add("#{attr_name}", "#{configuration[:message]}") unless #{attr_name} and #{attr_name}.to_s.match(/#{configuration[:with]}/)}))
         end
       end
+
+      # Validates whether the value of the specified attribute is available in a particular enumerable object.
+      #
+      #   class Person < ActiveRecord::Base
+      #     validates_inclusion_of :gender, :in=>%w( m f ), :message=>"woah! what are you then!??!!"
+      #     validates_inclusion_of :age, :in=>0..99
+      #   end
+      #
+      # Configuration options:
+      # ::in: An enumerable object of available items
+      # ::message: Specifieds a customer error message (default is: "is not included in the list")
+      def validates_inclusion_of(*attr_names)
+        configuration = { :message => ActiveRecord::Errors.default_error_messagess[:inclusion], :on => :save }
+        configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
+        enum = configuration[:in]
+
+        raise(ArgumentError, "An object with the method include? is required must be supplied as the :in option of the configuration hash") unless enum.respond_to?("include?")
+
+        for attr_name in attr_names
+          class_eval(%(#{validation_method(configuration[:on])} %{errors.add("#{attr_name}", "#{configuration[:message]}") unless (#{enum.inspect}).include?(#{attr_name}) }))
+        end
+      end
       
       private
         def validation_method(on)
@@ -290,6 +312,7 @@ module ActiveRecord
     end
     
     @@default_error_messagess = {
+      :inclusion => "is not included in the list",
       :invalid => "is invalid",
       :confirmation => "doesn't match confirmation",
       :accepted  => "must be accepted",
-- 
cgit v1.2.3