Ensure new validates works with uniqueness validator.
This commit is contained in:
parent
d4589e96ef
commit
93898b389b
|
@ -40,8 +40,7 @@ module ActiveRecord
|
|||
# not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
|
||||
# method, proc or string should return or evaluate to a true or false value.
|
||||
def validates_associated(*attr_names)
|
||||
options = attr_names.extract_options!
|
||||
validates_with AssociatedValidator, options.merge(:attributes => attr_names)
|
||||
validates_with AssociatedValidator, _merge_attributes(attr_names)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,10 +2,14 @@ module ActiveRecord
|
|||
module Validations
|
||||
class UniquenessValidator < ActiveModel::EachValidator
|
||||
def initialize(options)
|
||||
@klass = options.delete(:klass)
|
||||
super(options.reverse_merge(:case_sensitive => true))
|
||||
end
|
||||
|
||||
# Unfortunately, we have to tie Uniqueness validators to a class.
|
||||
def setup(klass)
|
||||
@klass = klass
|
||||
end
|
||||
|
||||
def validate_each(record, attribute, value)
|
||||
finder_class = find_finder_class_for(record)
|
||||
table = finder_class.active_relation
|
||||
|
@ -170,8 +174,7 @@ module ActiveRecord
|
|||
# such a case.
|
||||
#
|
||||
def validates_uniqueness_of(*attr_names)
|
||||
options = attr_names.extract_options!
|
||||
validates_with UniquenessValidator, options.merge(:attributes => attr_names, :klass => self)
|
||||
validates_with UniquenessValidator, _merge_attributes(attr_names)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,33 +10,29 @@ require 'models/interest'
|
|||
class AssociationValidationTest < ActiveRecord::TestCase
|
||||
fixtures :topics, :owners
|
||||
|
||||
repair_validations(Topic, Reply)
|
||||
repair_validations(Topic, Reply, Owner)
|
||||
|
||||
def test_validates_size_of_association
|
||||
repair_validations(Owner) do
|
||||
assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 }
|
||||
o = Owner.new('name' => 'nopets')
|
||||
assert !o.save
|
||||
assert o.errors[:pets].any?
|
||||
pet = o.pets.build('name' => 'apet')
|
||||
assert o.valid?
|
||||
end
|
||||
assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 }
|
||||
o = Owner.new('name' => 'nopets')
|
||||
assert !o.save
|
||||
assert o.errors[:pets].any?
|
||||
pet = o.pets.build('name' => 'apet')
|
||||
assert o.valid?
|
||||
end
|
||||
|
||||
def test_validates_size_of_association_using_within
|
||||
repair_validations(Owner) do
|
||||
assert_nothing_raised { Owner.validates_size_of :pets, :within => 1..2 }
|
||||
o = Owner.new('name' => 'nopets')
|
||||
assert !o.save
|
||||
assert o.errors[:pets].any?
|
||||
assert_nothing_raised { Owner.validates_size_of :pets, :within => 1..2 }
|
||||
o = Owner.new('name' => 'nopets')
|
||||
assert !o.save
|
||||
assert o.errors[:pets].any?
|
||||
|
||||
pet = o.pets.build('name' => 'apet')
|
||||
assert o.valid?
|
||||
pet = o.pets.build('name' => 'apet')
|
||||
assert o.valid?
|
||||
|
||||
2.times { o.pets.build('name' => 'apet') }
|
||||
assert !o.save
|
||||
assert o.errors[:pets].any?
|
||||
end
|
||||
2.times { o.pets.build('name' => 'apet') }
|
||||
assert !o.save
|
||||
assert o.errors[:pets].any?
|
||||
end
|
||||
|
||||
def test_validates_associated_many
|
||||
|
@ -55,51 +51,43 @@ class AssociationValidationTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_associated_one
|
||||
repair_validations(Reply) do
|
||||
Reply.validates_associated( :topic )
|
||||
Topic.validates_presence_of( :content )
|
||||
r = Reply.new("title" => "A reply", "content" => "with content!")
|
||||
r.topic = Topic.create("title" => "uhohuhoh")
|
||||
assert !r.valid?
|
||||
assert r.errors[:topic].any?
|
||||
r.topic.content = "non-empty"
|
||||
assert r.valid?
|
||||
end
|
||||
Reply.validates :topic, :associated => true
|
||||
Topic.validates_presence_of( :content )
|
||||
r = Reply.new("title" => "A reply", "content" => "with content!")
|
||||
r.topic = Topic.create("title" => "uhohuhoh")
|
||||
assert !r.valid?
|
||||
assert r.errors[:topic].any?
|
||||
r.topic.content = "non-empty"
|
||||
assert r.valid?
|
||||
end
|
||||
|
||||
def test_validates_associated_with_custom_message_using_quotes
|
||||
repair_validations(Reply) do
|
||||
Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes"
|
||||
Topic.validates_presence_of :content
|
||||
r = Reply.create("title" => "A reply", "content" => "with content!")
|
||||
r.topic = Topic.create("title" => "uhohuhoh")
|
||||
assert !r.valid?
|
||||
assert_equal ["This string contains 'single' and \"double\" quotes"], r.errors[:topic]
|
||||
end
|
||||
Reply.validates_associated :topic, :message=> "This string contains 'single' and \"double\" quotes"
|
||||
Topic.validates_presence_of :content
|
||||
r = Reply.create("title" => "A reply", "content" => "with content!")
|
||||
r.topic = Topic.create("title" => "uhohuhoh")
|
||||
assert !r.valid?
|
||||
assert_equal ["This string contains 'single' and \"double\" quotes"], r.errors[:topic]
|
||||
end
|
||||
|
||||
def test_validates_associated_missing
|
||||
repair_validations(Reply) do
|
||||
Reply.validates_presence_of(:topic)
|
||||
r = Reply.create("title" => "A reply", "content" => "with content!")
|
||||
assert !r.valid?
|
||||
assert r.errors[:topic].any?
|
||||
Reply.validates_presence_of(:topic)
|
||||
r = Reply.create("title" => "A reply", "content" => "with content!")
|
||||
assert !r.valid?
|
||||
assert r.errors[:topic].any?
|
||||
|
||||
r.topic = Topic.find :first
|
||||
assert r.valid?
|
||||
end
|
||||
r.topic = Topic.find :first
|
||||
assert r.valid?
|
||||
end
|
||||
|
||||
def test_validates_size_of_association_utf8
|
||||
repair_validations(Owner) do
|
||||
with_kcode('UTF8') do
|
||||
assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 }
|
||||
o = Owner.new('name' => 'あいうえおかきくけこ')
|
||||
assert !o.save
|
||||
assert o.errors[:pets].any?
|
||||
o.pets.build('name' => 'あいうえおかきくけこ')
|
||||
assert o.valid?
|
||||
end
|
||||
with_kcode('UTF8') do
|
||||
assert_nothing_raised { Owner.validates_size_of :pets, :minimum => 1 }
|
||||
o = Owner.new('name' => 'あいうえおかきくけこ')
|
||||
assert !o.save
|
||||
assert o.errors[:pets].any?
|
||||
o.pets.build('name' => 'あいうえおかきくけこ')
|
||||
assert o.valid?
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ end
|
|||
class UniquenessValidationTest < ActiveRecord::TestCase
|
||||
fixtures :topics, 'warehouse-things', :developers
|
||||
|
||||
repair_validations(Topic)
|
||||
repair_validations(Topic, Reply)
|
||||
|
||||
def test_validate_uniqueness
|
||||
Topic.validates_uniqueness_of(:title)
|
||||
|
@ -58,6 +58,15 @@ class UniquenessValidationTest < ActiveRecord::TestCase
|
|||
assert t2.save, "Should now save t2 as unique"
|
||||
end
|
||||
|
||||
def test_validates_uniqueness_with_validates
|
||||
Topic.validates :title, :uniqueness => true
|
||||
t = Topic.create!('title' => 'abc')
|
||||
|
||||
t2 = Topic.new('title' => 'abc')
|
||||
assert !t2.valid?
|
||||
assert t2.errors[:title]
|
||||
end
|
||||
|
||||
def test_validates_uniqueness_with_newline_chars
|
||||
Topic.validates_uniqueness_of(:title, :case_sensitive => false)
|
||||
|
||||
|
@ -66,24 +75,22 @@ class UniquenessValidationTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validate_uniqueness_with_scope
|
||||
repair_validations(Reply) do
|
||||
Reply.validates_uniqueness_of(:content, :scope => "parent_id")
|
||||
Reply.validates_uniqueness_of(:content, :scope => "parent_id")
|
||||
|
||||
t = Topic.create("title" => "I'm unique!")
|
||||
t = Topic.create("title" => "I'm unique!")
|
||||
|
||||
r1 = t.replies.create "title" => "r1", "content" => "hello world"
|
||||
assert r1.valid?, "Saving r1"
|
||||
r1 = t.replies.create "title" => "r1", "content" => "hello world"
|
||||
assert r1.valid?, "Saving r1"
|
||||
|
||||
r2 = t.replies.create "title" => "r2", "content" => "hello world"
|
||||
assert !r2.valid?, "Saving r2 first time"
|
||||
r2 = t.replies.create "title" => "r2", "content" => "hello world"
|
||||
assert !r2.valid?, "Saving r2 first time"
|
||||
|
||||
r2.content = "something else"
|
||||
assert r2.save, "Saving r2 second time"
|
||||
r2.content = "something else"
|
||||
assert r2.save, "Saving r2 second time"
|
||||
|
||||
t2 = Topic.create("title" => "I'm unique too!")
|
||||
r3 = t2.replies.create "title" => "r3", "content" => "hello world"
|
||||
assert r3.valid?, "Saving r3"
|
||||
end
|
||||
t2 = Topic.create("title" => "I'm unique too!")
|
||||
r3 = t2.replies.create "title" => "r3", "content" => "hello world"
|
||||
assert r3.valid?, "Saving r3"
|
||||
end
|
||||
|
||||
def test_validate_uniqueness_scoped_to_defining_class
|
||||
|
@ -102,29 +109,27 @@ class UniquenessValidationTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validate_uniqueness_with_scope_array
|
||||
repair_validations(Reply) do
|
||||
Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id])
|
||||
Reply.validates_uniqueness_of(:author_name, :scope => [:author_email_address, :parent_id])
|
||||
|
||||
t = Topic.create("title" => "The earth is actually flat!")
|
||||
t = Topic.create("title" => "The earth is actually flat!")
|
||||
|
||||
r1 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply"
|
||||
assert r1.valid?, "Saving r1"
|
||||
r1 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply"
|
||||
assert r1.valid?, "Saving r1"
|
||||
|
||||
r2 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply again..."
|
||||
assert !r2.valid?, "Saving r2. Double reply by same author."
|
||||
r2 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy@rubyonrails.com", "title" => "You're crazy!", "content" => "Crazy reply again..."
|
||||
assert !r2.valid?, "Saving r2. Double reply by same author."
|
||||
|
||||
r2.author_email_address = "jeremy_alt_email@rubyonrails.com"
|
||||
assert r2.save, "Saving r2 the second time."
|
||||
r2.author_email_address = "jeremy_alt_email@rubyonrails.com"
|
||||
assert r2.save, "Saving r2 the second time."
|
||||
|
||||
r3 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy_alt_email@rubyonrails.com", "title" => "You're wrong", "content" => "It's cubic"
|
||||
assert !r3.valid?, "Saving r3"
|
||||
r3 = t.replies.create "author_name" => "jeremy", "author_email_address" => "jeremy_alt_email@rubyonrails.com", "title" => "You're wrong", "content" => "It's cubic"
|
||||
assert !r3.valid?, "Saving r3"
|
||||
|
||||
r3.author_name = "jj"
|
||||
assert r3.save, "Saving r3 the second time."
|
||||
r3.author_name = "jj"
|
||||
assert r3.save, "Saving r3 the second time."
|
||||
|
||||
r3.author_name = "jeremy"
|
||||
assert !r3.save, "Saving r3 the third time."
|
||||
end
|
||||
r3.author_name = "jeremy"
|
||||
assert !r3.save, "Saving r3 the third time."
|
||||
end
|
||||
|
||||
def test_validate_case_insensitive_uniqueness
|
||||
|
|
Loading…
Reference in New Issue