mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix uniqueness validation with an after_create hook.
record.id_was is nil in after_create/after_save, so we should use id in these cases. While this logic feels incomplete, the existing update_record uses the same logic:2fda4e0874/activerecord/lib/active_record/relation.rb (L83)
This logic was originally added for a similar problem: updates not working with after_create hook. See:482f8c15b1
Followup to #23581 Fixes #23844
This commit is contained in:
parent
2fda4e0874
commit
0379da6abc
2 changed files with 19 additions and 1 deletions
|
@ -18,7 +18,7 @@ module ActiveRecord
|
|||
relation = build_relation(finder_class, table, attribute, value)
|
||||
if record.persisted?
|
||||
if finder_class.primary_key
|
||||
relation = relation.where.not(finder_class.primary_key => record.id_was)
|
||||
relation = relation.where.not(finder_class.primary_key => record.id_was || record.id)
|
||||
else
|
||||
raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.")
|
||||
end
|
||||
|
|
|
@ -53,6 +53,14 @@ class CoolTopic < Topic
|
|||
validates_uniqueness_of :id
|
||||
end
|
||||
|
||||
class TopicWithAfterCreate < Topic
|
||||
after_create :set_author
|
||||
|
||||
def set_author
|
||||
update_attributes!(:author_name => "#{title} #{id}")
|
||||
end
|
||||
end
|
||||
|
||||
class UniquenessValidationTest < ActiveRecord::TestCase
|
||||
INT_MAX_VALUE = 2147483647
|
||||
|
||||
|
@ -469,6 +477,16 @@ class UniquenessValidationTest < ActiveRecord::TestCase
|
|||
assert t.save, "Should still save t as unique"
|
||||
end
|
||||
|
||||
def test_validate_uniqueness_with_after_create_performing_save
|
||||
TopicWithAfterCreate.validates_uniqueness_of(:title)
|
||||
topic = TopicWithAfterCreate.create!(:title => "Title1")
|
||||
assert topic.author_name.start_with?("Title1")
|
||||
|
||||
topic2 = TopicWithAfterCreate.new(:title => "Title1")
|
||||
refute topic2.valid?
|
||||
assert_equal(["has already been taken"], topic2.errors[:title])
|
||||
end
|
||||
|
||||
def test_validate_uniqueness_uuid
|
||||
skip unless current_adapter?(:PostgreSQLAdapter)
|
||||
item = UuidItem.create!(uuid: SecureRandom.uuid, title: 'item1')
|
||||
|
|
Loading…
Reference in a new issue