From 6185c4947e88f1b6b7c2adaabf62081bac6df04a Mon Sep 17 00:00:00 2001 From: Mattias Pfeiffer Date: Wed, 7 Mar 2012 12:51:43 +0100 Subject: Add :conditions option to uniqueness validator --- activerecord/lib/active_record/validations/uniqueness.rb | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index 9556878f63..eb3a34c4cc 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -35,8 +35,8 @@ module ActiveRecord relation = relation.and(table[scope_item].eq(scope_value)) end - if finder_class.unscoped.where(relation).exists? - record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value)) + if finder_class.unscoped.where(relation).where(options[:conditions]).exists? + record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope, :conditions).merge(:value => value)) end end @@ -102,6 +102,14 @@ module ActiveRecord # validates_uniqueness_of :teacher_id, :scope => [:semester_id, :class_id] # end # + # It is also possible to limit the uniqueness constraint to a set of records matching certain conditions. + # In this example archived articles with are not being taken into consideration when validating uniqueness + # of the title attribute: + # + # class Article < ActiveRecord::Base + # validates_uniqueness_of :title, :conditions => ['status != ?', 'archived'] + # end + # # When the record is created, a check is performed to make sure that no record exists in the database # with the given value for the specified attribute (that maps to a column). When the record is updated, # the same check is made but disregarding the record itself. @@ -109,6 +117,8 @@ module ActiveRecord # Configuration options: # * :message - Specifies a custom error message (default is: "has already been taken"). # * :scope - One or more columns by which to limit the scope of the uniqueness constraint. + # * :conditions - Specify the conditions to be included as a WHERE SQL fragment to limit + # the uniqueness constraint lookup. (e.g. :conditions => {:status => 'active'}) # * :case_sensitive - Looks for an exact match. Ignored by non-text columns (+true+ by default). # * :allow_nil - If set to true, skips this validation if the attribute is +nil+ (default is +false+). # * :allow_blank - If set to true, skips this validation if the attribute is blank (default is +false+). -- cgit v1.2.3 From 3d8592657fce0c08e65d52bab00104a552b955cd Mon Sep 17 00:00:00 2001 From: Mattias Pfeiffer Date: Wed, 7 Mar 2012 15:59:28 +0100 Subject: Change syntax to accept an AR::Relation instead of old conditions hash/array. --- activerecord/lib/active_record/validations/uniqueness.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index eb3a34c4cc..9cba2de055 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -35,7 +35,13 @@ module ActiveRecord relation = relation.and(table[scope_item].eq(scope_value)) end - if finder_class.unscoped.where(relation).where(options[:conditions]).exists? + relation = finder_class.unscoped.where(relation) + + if options[:conditions] + relation = relation.merge(options[:conditions]) + end + + if relation.exists? record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope, :conditions).merge(:value => value)) end end @@ -107,7 +113,7 @@ module ActiveRecord # of the title attribute: # # class Article < ActiveRecord::Base - # validates_uniqueness_of :title, :conditions => ['status != ?', 'archived'] + # validates_uniqueness_of :title, :conditions => where('status != ?', 'archived') # end # # When the record is created, a check is performed to make sure that no record exists in the database @@ -118,7 +124,7 @@ module ActiveRecord # * :message - Specifies a custom error message (default is: "has already been taken"). # * :scope - One or more columns by which to limit the scope of the uniqueness constraint. # * :conditions - Specify the conditions to be included as a WHERE SQL fragment to limit - # the uniqueness constraint lookup. (e.g. :conditions => {:status => 'active'}) + # the uniqueness constraint lookup. (e.g. :conditions => where('status = ?', 'active')) # * :case_sensitive - Looks for an exact match. Ignored by non-text columns (+true+ by default). # * :allow_nil - If set to true, skips this validation if the attribute is +nil+ (default is +false+). # * :allow_blank - If set to true, skips this validation if the attribute is blank (default is +false+). -- cgit v1.2.3 From 4b6daef3fc0f1edc5bfdcfb4e0a9572f1f4f56ec Mon Sep 17 00:00:00 2001 From: Mattias Pfeiffer Date: Wed, 7 Mar 2012 16:36:03 +0100 Subject: Correct grammar in documentation --- activerecord/lib/active_record/validations/uniqueness.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb index 9cba2de055..db618f617f 100644 --- a/activerecord/lib/active_record/validations/uniqueness.rb +++ b/activerecord/lib/active_record/validations/uniqueness.rb @@ -109,7 +109,7 @@ module ActiveRecord # end # # It is also possible to limit the uniqueness constraint to a set of records matching certain conditions. - # In this example archived articles with are not being taken into consideration when validating uniqueness + # In this example archived articles are not being taken into consideration when validating uniqueness # of the title attribute: # # class Article < ActiveRecord::Base -- cgit v1.2.3