Skip to content
This repository
Browse code

Don't enable validations when passing false hash values to ActiveMode…

…l.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.)
  • Loading branch information...
commit b3ccd7b27afabacba5f537ef5c428314df25eae3 1 parent 5acb10d
Steve Purcell authored May 28, 2012
2  activemodel/CHANGELOG.md
Source Rendered
... ...
@@ -1,5 +1,7 @@
1 1
 ## Rails 4.0.0 (unreleased) ##
2 2
 
  3
+*   Passing false hash values to `validates` will no longer enable the corresponding validators *Steve Purcell*
  4
+
3 5
 *   `ConfirmationValidator` error messages will attach to `:#{attribute}_confirmation` instead of `attribute` *Brian Cardarella*
4 6
 
5 7
 *   Added ActiveModel::Model, a mixin to make Ruby objects work with AP out of box *Guillermo Iguaran*
1  activemodel/lib/active_model/validations/validates.rb
@@ -88,6 +88,7 @@ def validates(*attributes)
88 88
         defaults.merge!(:attributes => attributes)
89 89
 
90 90
         validations.each do |key, options|
  91
+          next unless options
91 92
           key = "#{key.to_s.camelize}Validator"
92 93
 
93 94
           begin
5  activemodel/test/cases/validations_test.rb
@@ -330,6 +330,11 @@ def test_validates_with_bang
330 330
     end
331 331
   end
332 332
 
  333
+  def test_validates_with_false_hash_value
  334
+    Topic.validates :title,  :presence => false
  335
+    assert Topic.new.valid?
  336
+  end
  337
+
333 338
   def test_strict_validation_error_message
334 339
     Topic.validates :title, :strict => true, :presence => true
335 340
 

0 notes on commit b3ccd7b

Please sign in to comment.
Something went wrong with that request. Please try again.