1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #36210 from vishaltelangre/raise-record-invalid-when-associations-fail-to-save-due-to-uniqueness-failure

Fix: ActiveRecord::RecordInvalid is not raised when an associated record fails to #save! due to uniqueness validation failure
This commit is contained in:
Rafael França 2019-06-24 13:59:15 -04:00 committed by GitHub
commit b65f88652f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 1 deletions

View file

@ -409,7 +409,7 @@ module ActiveRecord
saved = record.save(validate: false) saved = record.save(validate: false)
end end
raise ActiveRecord::Rollback unless saved raise(RecordInvalid.new(association.owner)) unless saved
end end
end end
end end

View file

@ -2,6 +2,7 @@
require "cases/helper" require "cases/helper"
require "models/author" require "models/author"
require "models/book"
require "models/bird" require "models/bird"
require "models/post" require "models/post"
require "models/comment" require "models/comment"
@ -1671,6 +1672,10 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te
super super
@pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?") @pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
@pirate.birds.create(name: "cookoo") @pirate.birds.create(name: "cookoo")
@author = Author.new(name: "DHH")
@author.published_books.build(name: "Rework", isbn: "1234")
@author.published_books.build(name: "Remote", isbn: "1234")
end end
test "should automatically validate associations" do test "should automatically validate associations" do
@ -1679,6 +1684,42 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te
assert_not_predicate @pirate, :valid? assert_not_predicate @pirate, :valid?
end end
test "rollbacks whole transaction and raises ActiveRecord::RecordInvalid when associations fail to #save! due to uniqueness validation failure" do
author_count_before_save = Author.count
book_count_before_save = Book.count
assert_no_difference "Author.count" do
assert_no_difference "Book.count" do
exception = assert_raises(ActiveRecord::RecordInvalid) do
@author.save!
end
assert_equal("Validation failed: Published books is invalid", exception.message)
end
end
assert_equal(author_count_before_save, Author.count)
assert_equal(book_count_before_save, Book.count)
end
test "rollbacks whole transaction when associations fail to #save due to uniqueness validation failure" do
author_count_before_save = Author.count
book_count_before_save = Book.count
assert_no_difference "Author.count" do
assert_no_difference "Book.count" do
assert_nothing_raised do
result = @author.save
assert_not(result)
end
end
end
assert_equal(author_count_before_save, Author.count)
assert_equal(book_count_before_save, Book.count)
end
end end
class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::TestCase class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::TestCase

View file

@ -116,6 +116,7 @@ class Author < ActiveRecord::Base
has_many :tags_with_primary_key, through: :posts has_many :tags_with_primary_key, through: :posts
has_many :books has_many :books
has_many :published_books, class_name: "PublishedBook"
has_many :unpublished_books, -> { where(status: [:proposed, :written]) }, class_name: "Book" has_many :unpublished_books, -> { where(status: [:proposed, :written]) }, class_name: "Book"
has_many :subscriptions, through: :books has_many :subscriptions, through: :books
has_many :subscribers, -> { order("subscribers.nick") }, through: :subscriptions has_many :subscribers, -> { order("subscribers.nick") }, through: :subscriptions

View file

@ -24,3 +24,9 @@ class Book < ActiveRecord::Base
"do publish work..." "do publish work..."
end end
end end
class PublishedBook < ActiveRecord::Base
self.table_name = "books"
validates_uniqueness_of :isbn
end