rails/rails — pull request #6516 by purcell (2012-05-28 13:45:24+00:00)
Title: 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.)