aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/autosave_association_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases/autosave_association_test.rb')
-rw-r--r--activerecord/test/cases/autosave_association_test.rb102
1 files changed, 77 insertions, 25 deletions
diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb
index 88df0eed55..2d223a3035 100644
--- a/activerecord/test/cases/autosave_association_test.rb
+++ b/activerecord/test/cases/autosave_association_test.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
require "cases/helper"
+require "models/author"
+require "models/book"
require "models/bird"
require "models/post"
require "models/comment"
@@ -38,7 +40,6 @@ class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase
def self.name; "Person"; end
private
-
def should_be_cool
unless first_name == "cool"
errors.add :first_name, "not cool"
@@ -81,7 +82,6 @@ class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase
end
private
-
def assert_no_difference_when_adding_callbacks_twice_for(model, association_name)
reflection = model.reflect_on_association(association_name)
assert_no_difference "callbacks_for_model(#{model.name}).length" do
@@ -643,10 +643,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
def test_build_before_save
company = companies(:first_firm)
- # Load schema information so we don't query below if running just this test.
- Client.define_attribute_methods
-
- new_client = assert_no_queries { company.clients_of_firm.build("name" => "Another Client") }
+ new_client = assert_queries(0) { company.clients_of_firm.build("name" => "Another Client") }
assert_not_predicate company.clients_of_firm, :loaded?
company.name += "-changed"
@@ -658,10 +655,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
def test_build_many_before_save
company = companies(:first_firm)
- # Load schema information so we don't query below if running just this test.
- Client.define_attribute_methods
-
- assert_no_queries { company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) }
+ assert_queries(0) { company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) }
company.name += "-changed"
assert_queries(3) { assert company.save }
@@ -671,10 +665,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
def test_build_via_block_before_save
company = companies(:first_firm)
- # Load schema information so we don't query below if running just this test.
- Client.define_attribute_methods
-
- new_client = assert_no_queries { company.clients_of_firm.build { |client| client.name = "Another Client" } }
+ new_client = assert_queries(0) { company.clients_of_firm.build { |client| client.name = "Another Client" } }
assert_not_predicate company.clients_of_firm, :loaded?
company.name += "-changed"
@@ -686,10 +677,7 @@ class TestDefaultAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCa
def test_build_many_via_block_before_save
company = companies(:first_firm)
- # Load schema information so we don't query below if running just this test.
- Client.define_attribute_methods
-
- assert_no_queries do
+ assert_queries(0) do
company.clients_of_firm.build([{ "name" => "Another Client" }, { "name" => "Another Client II" }]) do |client|
client.name = "changed"
end
@@ -1319,21 +1307,45 @@ end
class TestAutosaveAssociationOnAHasOneThroughAssociation < ActiveRecord::TestCase
self.use_transactional_tests = false unless supports_savepoints?
- def setup
- super
+ def create_member_with_organization
organization = Organization.create
- @member = Member.create
- MemberDetail.create(organization: organization, member: @member)
+ member = Member.create
+ MemberDetail.create(organization: organization, member: member)
+
+ member
end
def test_should_not_has_one_through_model
- class << @member.organization
+ member = create_member_with_organization
+
+ class << member.organization
+ def save(*args)
+ super
+ raise "Oh noes!"
+ end
+ end
+ assert_nothing_raised { member.save }
+ end
+
+ def create_author_with_post_with_comment
+ Author.create! name: "David" # make comment_id not match author_id
+ author = Author.create! name: "Sergiy"
+ post = Post.create! author: author, title: "foo", body: "bar"
+ Comment.create! post: post, body: "cool comment"
+
+ author
+ end
+
+ def test_should_not_reversed_has_one_through_model
+ author = create_author_with_post_with_comment
+
+ class << author.comment_on_first_post
def save(*args)
super
raise "Oh noes!"
end
end
- assert_nothing_raised { @member.save }
+ assert_nothing_raised { author.save }
end
end
@@ -1660,6 +1672,10 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te
super
@pirate = Pirate.create(catchphrase: "Don' botharrr talkin' like one, savvy?")
@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
test "should automatically validate associations" do
@@ -1668,6 +1684,42 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te
assert_not_predicate @pirate, :valid?
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
class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::TestCase
@@ -1806,7 +1858,7 @@ class TestAutosaveAssociationOnAHasManyAssociationWithInverse < ActiveRecord::Te
end
class TestAutosaveAssociationOnAHasManyAssociationDefinedInSubclassWithAcceptsNestedAttributes < ActiveRecord::TestCase
- def test_should_update_children_when_asssociation_redefined_in_subclass
+ def test_should_update_children_when_association_redefined_in_subclass
agency = Agency.create!(name: "Agency")
valid_project = Project.create!(firm: agency, name: "Initial")
agency.update!(