From 2438a1cf4ed85552d11b0ac66ef6adacde08f281 Mon Sep 17 00:00:00 2001 From: Akshat Sharma Date: Tue, 1 Sep 2015 10:42:51 +0530 Subject: [PATCH] Add case_sensitive option for confirmation validation Case :- 1. In case of email confirmation one needs case insensitive comparison 2. In case of password confirmation one needs case sensitive comparison [ci skip] Update Guides for case_sensitive option in confirmation validation --- activemodel/CHANGELOG.md | 6 ++++++ .../active_model/validations/confirmation.rb | 20 +++++++++++++++---- guides/source/active_record_validations.md | 10 ++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md index 5588699d9b..5b0f2cd666 100644 --- a/activemodel/CHANGELOG.md +++ b/activemodel/CHANGELOG.md @@ -58,4 +58,10 @@ *Henrik Nyh* +* Add case_sensitive option for confirmation validator in models. + + See #17351 + + *Akshat Sharma* + Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/activemodel/CHANGELOG.md) for previous changes. diff --git a/activemodel/lib/active_model/validations/confirmation.rb b/activemodel/lib/active_model/validations/confirmation.rb index 1b11c28087..3b2093aef9 100644 --- a/activemodel/lib/active_model/validations/confirmation.rb +++ b/activemodel/lib/active_model/validations/confirmation.rb @@ -3,14 +3,16 @@ module ActiveModel module Validations class ConfirmationValidator < EachValidator # :nodoc: def initialize(options) - super + super({ case_sensitive: true }.merge!(options)) setup!(options[:class]) end def validate_each(record, attribute, value) - if (confirmed = record.send("#{attribute}_confirmation")) && (value != confirmed) - human_attribute_name = record.class.human_attribute_name(attribute) - record.errors.add(:"#{attribute}_confirmation", :confirmation, options.merge(attribute: human_attribute_name)) + if (confirmed = record.send("#{attribute}_confirmation")) + unless confimation_value_equal?(record, attribute, value, confirmed) + human_attribute_name = record.class.human_attribute_name(attribute) + record.errors.add(:"#{attribute}_confirmation", :confirmation, options.merge(attribute: human_attribute_name)) + end end end @@ -24,6 +26,14 @@ module ActiveModel :"#{attribute}_confirmation" unless klass.method_defined?(:"#{attribute}_confirmation=") end.compact) end + + def confimation_value_equal?(record, attribute, value, confirmed) + if !options[:case_sensitive] && value.is_a? String + value.casecmp(confirmed) == 0 + else + value == confirmed + end + end end module HelperMethods @@ -55,6 +65,8 @@ module ActiveModel # Configuration options: # * :message - A custom error message (default is: "doesn't match # %{translated_attribute_name}"). + # * :case_sensitive - Looks for an exact match. Ignored by + # non-text columns (+true+ by default). # # There is also a list of default options supported by every validator: # +:if+, +:unless+, +:on+, +:allow_nil+, +:allow_blank+, and +:strict+. diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md index 1c1b863fe9..83eee4e0f4 100644 --- a/guides/source/active_record_validations.md +++ b/guides/source/active_record_validations.md @@ -327,6 +327,16 @@ class Person < ActiveRecord::Base end ``` +There is also a `:case_sensitive` option that you can use to define whether the +confirmation constraint will be case sensitive or not. This option defaults to +true. + +```ruby +class Person < ActiveRecord::Base + validates :email, confirmation: { case_sensitive: false } +end +``` + The default error message for this helper is _"doesn't match confirmation"_. ### `exclusion`