From b3ccd7b27afabacba5f537ef5c428314df25eae3 Mon Sep 17 00:00:00 2001 From: Steve Purcell Date: Mon, 28 May 2012 14:39:09 +0100 Subject: Don't enable validations when passing false hash values to ActiveModel.validates Passing a falsey option value for a validator currently causes that validator to be enabled, just like "true": ActiveModel.validates :foo, :presence => false This is rather counterintuitive, and makes it inconvenient to wrap `validates` in methods which may conditionally enable different validators. As an example, one is currently forced to write: def has_slug(source_field, options={:unique => true}) slugger = Proc.new { |r| r[:slug] = self.class.sluggify(r[source_field]) if r[:slug].blank? } before_validation slugger validations = { :presence => true, :slug => true } if options[:unique] validations[:uniqueness] = true end validates :slug, validations end because the following reasonable-looking alternative fails to work as expected: def has_slug(source_field, options={:unique => true}) slugger = Proc.new { |r| r[:slug] = self.class.sluggify(r[source_field]) if r[:slug].blank? } before_validation slugger validates :slug, :presence => true, :slug => true, :uniqueness => options[:unique] end (This commit includes a test, and all activemodel and activerecord tests pass as before.) --- activemodel/CHANGELOG.md | 2 ++ activemodel/lib/active_model/validations/validates.rb | 1 + activemodel/test/cases/validations_test.rb | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 789cff0673..eb34edb91b 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -1,5 +1,7 @@ ## Rails 4.0.0 (unreleased) ## +* Passing false hash values to `validates` will no longer enable the corresponding validators *Steve Purcell* + * `ConfirmationValidator` error messages will attach to `:#{attribute}_confirmation` instead of `attribute` *Brian Cardarella* * Added ActiveModel::Model, a mixin to make Ruby objects work with AP out of box *Guillermo Iguaran* diff --git a/activemodel/lib/active_model/validations/validates.rb b/activemodel/lib/active_model/validations/validates.rb index d94c4e3f4f..6c13d2b4a2 100644 --- a/activemodel/lib/active_model/validations/validates.rb +++ b/activemodel/lib/active_model/validations/validates.rb @@ -88,6 +88,7 @@ module ActiveModel defaults.merge!(:attributes => attributes) validations.each do |key, options| + next unless options key = "#{key.to_s.camelize}Validator" begin diff --git a/activemodel/test/cases/validations_test.rb b/activemodel/test/cases/validations_test.rb index 1f5023bf76..8ea9745fbf 100644 --- a/activemodel/test/cases/validations_test.rb +++ b/activemodel/test/cases/validations_test.rb @@ -330,6 +330,11 @@ class ValidationsTest < ActiveModel::TestCase end end + def test_validates_with_false_hash_value + Topic.validates :title, :presence => false + assert Topic.new.valid? + end + def test_strict_validation_error_message Topic.validates :title, :strict => true, :presence => true -- cgit v1.2.3