Merge pull request #5321 from pfeiffer/uniqueness_validator_conditions
Add :conditions option to uniqueness validator
This commit is contained in:
commit
4711298767
@ -35,8 +35,14 @@ def validate_each(record, attribute, value)
|
||||
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))
|
||||
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
|
||||
|
||||
@ -102,6 +108,14 @@ module ClassMethods
|
||||
# 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 are not being taken into consideration when validating uniqueness
|
||||
# of the title attribute:
|
||||
#
|
||||
# class Article < ActiveRecord::Base
|
||||
# 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
|
||||
# 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 +123,8 @@ module ClassMethods
|
||||
# Configuration options:
|
||||
# * <tt>:message</tt> - Specifies a custom error message (default is: "has already been taken").
|
||||
# * <tt>:scope</tt> - One or more columns by which to limit the scope of the uniqueness constraint.
|
||||
# * <tt>:conditions</tt> - Specify the conditions to be included as a <tt>WHERE</tt> SQL fragment to limit
|
||||
# the uniqueness constraint lookup. (e.g. <tt>:conditions => where('status = ?', 'active')</tt>)
|
||||
# * <tt>:case_sensitive</tt> - Looks for an exact match. Ignored by non-text columns (+true+ by default).
|
||||
# * <tt>:allow_nil</tt> - If set to true, skips this validation if the attribute is +nil+ (default is +false+).
|
||||
# * <tt>:allow_blank</tt> - If set to true, skips this validation if the attribute is blank (default is +false+).
|
||||
|
@ -325,4 +325,16 @@ def test_validate_straight_inheritance_uniqueness
|
||||
assert w6.errors[:city].any?, "Should have errors for city"
|
||||
assert_equal ["has already been taken"], w6.errors[:city], "Should have uniqueness message for city"
|
||||
end
|
||||
|
||||
def test_validate_uniqueness_with_conditions
|
||||
Topic.validates_uniqueness_of(:title, :conditions => Topic.where('approved = ?', true))
|
||||
t1 = Topic.create("title" => "I'm a topic", "approved" => true)
|
||||
t2 = Topic.create("title" => "I'm an unapproved topic", "approved" => false)
|
||||
|
||||
t3 = Topic.new("title" => "I'm a topic", "approved" => true)
|
||||
assert !t3.valid?, "t3 shouldn't be valid"
|
||||
|
||||
t4 = Topic.new("title" => "I'm an unapproved topic", "approved" => false)
|
||||
assert t4.valid?, "t4 should be valid"
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user