aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabriel Sobrinho <gabriel.sobrinho@gmail.com>2012-08-12 17:38:22 -0300
committerGabriel Sobrinho <gabriel.sobrinho@gmail.com>2012-08-24 15:26:17 -0300
commit2f3eb484f2712ba1833fea758ee85e49c374fc5b (patch)
tree119c197b8f2b746ed55e6cac2ab2f3d562a2659c
parent2c571b3f0544a6457db4818e752f4cd4bacd48b4 (diff)
downloadrails-2f3eb484f2712ba1833fea758ee85e49c374fc5b.tar.gz
rails-2f3eb484f2712ba1833fea758ee85e49c374fc5b.tar.bz2
rails-2f3eb484f2712ba1833fea758ee85e49c374fc5b.zip
Accept a symbol for `:in` option on inclusion and exclusion validators
-rw-r--r--activemodel/CHANGELOG.md6
-rw-r--r--activemodel/lib/active_model/validations/clusivity.rb13
-rw-r--r--activemodel/lib/active_model/validations/exclusion.rb3
-rw-r--r--activemodel/lib/active_model/validations/inclusion.rb3
-rw-r--r--activemodel/test/cases/validations/exclusion_validation_test.rb22
-rw-r--r--activemodel/test/cases/validations/inclusion_validation_test.rb22
6 files changed, 64 insertions, 5 deletions
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index a8f470397b..1916c3439a 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -1,5 +1,11 @@
## Rails 4.0.0 (unreleased) ##
+* Changed inclusion and exclusion validators to accept a symbol for `:in` option.
+
+ This allows to use dynamic inclusion/exclusion values using methods, besides the current lambda/proc support.
+
+ *Gabriel Sobrinho*
+
* `AM::Validation#validates` ability to pass custom exception to `:strict` option.
*Bogdan Gusiev*
diff --git a/activemodel/lib/active_model/validations/clusivity.rb b/activemodel/lib/active_model/validations/clusivity.rb
index 643a6f2b7c..cf1415b6c2 100644
--- a/activemodel/lib/active_model/validations/clusivity.rb
+++ b/activemodel/lib/active_model/validations/clusivity.rb
@@ -3,11 +3,11 @@ require 'active_support/core_ext/range.rb'
module ActiveModel
module Validations
module Clusivity #:nodoc:
- ERROR_MESSAGE = "An object with the method #include? or a proc or lambda is required, " <<
+ ERROR_MESSAGE = "An object with the method #include? or a proc, lambda or symbol is required, " <<
"and must be supplied as the :in (or :within) option of the configuration hash"
def check_validity!
- unless [:include?, :call].any?{ |method| delimiter.respond_to?(method) }
+ unless delimiter.respond_to?(:include?) || delimiter.respond_to?(:call) || delimiter.respond_to?(:to_sym)
raise ArgumentError, ERROR_MESSAGE
end
end
@@ -15,7 +15,14 @@ module ActiveModel
private
def include?(record, value)
- exclusions = delimiter.respond_to?(:call) ? delimiter.call(record) : delimiter
+ exclusions = if delimiter.respond_to?(:call)
+ delimiter.call(record)
+ elsif delimiter.respond_to?(:to_sym)
+ record.send(delimiter)
+ else
+ delimiter
+ end
+
exclusions.send(inclusion_method(exclusions), value)
end
diff --git a/activemodel/lib/active_model/validations/exclusion.rb b/activemodel/lib/active_model/validations/exclusion.rb
index dc3368c569..3ec552c372 100644
--- a/activemodel/lib/active_model/validations/exclusion.rb
+++ b/activemodel/lib/active_model/validations/exclusion.rb
@@ -24,11 +24,12 @@ module ActiveModel
# validates_exclusion_of :format, in: %w( mov avi ), message: "extension %{value} is not allowed"
# validates_exclusion_of :password, in: ->(person) { [person.username, person.first_name] },
# message: 'should not be the same as your username or first name'
+ # validates_exclusion_of :karma, in: :reserved_karmas
# end
#
# Configuration options:
# * <tt>:in</tt> - An enumerable object of items that the value shouldn't
- # be part of. This can be supplied as a proc or lambda which returns an
+ # be part of. This can be supplied as a proc, lambda or symbol which returns an
# enumerable. If the enumerable is a range the test is performed with
# * <tt>:within</tt> - A synonym(or alias) for <tt>:in</tt>
# <tt>Range#cover?</tt>, otherwise with <tt>include?</tt>.
diff --git a/activemodel/lib/active_model/validations/inclusion.rb b/activemodel/lib/active_model/validations/inclusion.rb
index c2835c550b..babc8982da 100644
--- a/activemodel/lib/active_model/validations/inclusion.rb
+++ b/activemodel/lib/active_model/validations/inclusion.rb
@@ -23,11 +23,12 @@ module ActiveModel
# validates_inclusion_of :age, in: 0..99
# validates_inclusion_of :format, in: %w( jpg gif png ), message: "extension %{value} is not included in the list"
# validates_inclusion_of :states, in: ->(person) { STATES[person.country] }
+ # validates_inclusion_of :karma, in: :available_karmas
# end
#
# Configuration options:
# * <tt>:in</tt> - An enumerable object of available items. This can be
- # supplied as a proc or lambda which returns an enumerable. If the
+ # supplied as a proc, lambda or symbol which returns an enumerable. If the
# enumerable is a range the test is performed with <tt>Range#cover?</tt>,
# otherwise with <tt>include?</tt>.
# * <tt>:within</tt> - A synonym(or alias) for <tt>:in</tt>
diff --git a/activemodel/test/cases/validations/exclusion_validation_test.rb b/activemodel/test/cases/validations/exclusion_validation_test.rb
index baccf72ecb..9f916dbfdd 100644
--- a/activemodel/test/cases/validations/exclusion_validation_test.rb
+++ b/activemodel/test/cases/validations/exclusion_validation_test.rb
@@ -64,4 +64,26 @@ class ExclusionValidationTest < ActiveModel::TestCase
t.title = "wasabi"
assert t.valid?
end
+
+ def test_validates_inclusion_of_with_symbol
+ Person.validates_exclusion_of :karma, :in => :reserved_karmas
+
+ p = Person.new
+ p.karma = "abe"
+
+ def p.reserved_karmas
+ %w(abe)
+ end
+
+ assert p.invalid?
+ assert_equal ["is reserved"], p.errors[:karma]
+
+ def p.reserved_karmas
+ %w()
+ end
+
+ assert p.valid?
+ ensure
+ Person.reset_callbacks(:validate)
+ end
end
diff --git a/activemodel/test/cases/validations/inclusion_validation_test.rb b/activemodel/test/cases/validations/inclusion_validation_test.rb
index c57fa75faf..92638f8e70 100644
--- a/activemodel/test/cases/validations/inclusion_validation_test.rb
+++ b/activemodel/test/cases/validations/inclusion_validation_test.rb
@@ -96,4 +96,26 @@ class InclusionValidationTest < ActiveModel::TestCase
t.title = "elephant"
assert t.valid?
end
+
+ def test_validates_inclusion_of_with_symbol
+ Person.validates_inclusion_of :karma, :in => :available_karmas
+
+ p = Person.new
+ p.karma = "Lifo"
+
+ def p.available_karmas
+ %w()
+ end
+
+ assert p.invalid?
+ assert_equal ["is not included in the list"], p.errors[:karma]
+
+ def p.available_karmas
+ %w(Lifo)
+ end
+
+ assert p.valid?
+ ensure
+ Person.reset_callbacks(:validate)
+ end
end