From 6f082a0272f9f44e6e24278004b034a86c79a251 Mon Sep 17 00:00:00 2001 From: Eloy Duran Date: Wed, 4 Feb 2009 21:40:53 +0100 Subject: [PATCH] Also save :autosave enabled associations when #save! is used. --- .../lib/active_record/autosave_association.rb | 12 ++++++++++ .../test/cases/autosave_association_test.rb | 24 +++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index 07660eb..680b415 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -129,6 +129,7 @@ module ActiveRecord base.class_eval do alias_method_chain :reload, :autosave_associations alias_method_chain :save, :autosave_associations + alias_method_chain :save!, :autosave_associations alias_method_chain :valid?, :autosave_associations %w{ has_one belongs_to has_many has_and_belongs_to_many }.each do |type| @@ -161,6 +162,17 @@ module ActiveRecord end end + # Attempts to save the record just like save_with_autosave_associations but + # will raise a RecordInvalid exception instead of returning false if the + # record is not valid. + def save_with_autosave_associations! + if valid_with_autosave_associations? + save_with_autosave_associations(false) || raise(RecordNotSaved) + else + raise RecordInvalid.new(self) + end + end + # Returns whether or not the parent, self, and any loaded autosave associations are valid. def valid_with_autosave_associations? if valid_without_autosave_associations? diff --git a/activerecord/test/cases/autosave_association_test.rb b/activerecord/test/cases/autosave_association_test.rb index 3c656b2..381249c 100644 --- a/activerecord/test/cases/autosave_association_test.rb +++ b/activerecord/test/cases/autosave_association_test.rb @@ -169,6 +169,12 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase assert_equal 'The Vile Insanity', @pirate.reload.ship.name end + def test_should_automatically_save_bang_the_associated_model + @pirate.ship.name = 'The Vile Insanity' + @pirate.save! + assert_equal 'The Vile Insanity', @pirate.reload.ship.name + end + def test_should_automatically_validate_the_associated_model @pirate.ship.name = '' assert !@pirate.valid? @@ -245,6 +251,12 @@ class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase assert_equal 'Arr', @ship.reload.pirate.catchphrase end + def test_should_automatically_save_bang_the_associated_model + @ship.pirate.catchphrase = 'Arr' + @ship.save! + assert_equal 'Arr', @ship.reload.pirate.catchphrase + end + def test_should_automatically_validate_the_associated_model @ship.pirate.catchphrase = '' assert !@ship.valid? @@ -298,6 +310,14 @@ module AutosaveAssociationOnACollectionAssociationTests assert_equal new_names, @pirate.reload.send(@association_name).map(&:name) end + def test_should_automatically_save_bang_the_associated_models + new_names = ['Grace OMalley', 'Privateers Greed'] + @pirate.send(@association_name).each_with_index { |child, i| child.name = new_names[i] } + + @pirate.save! + assert_equal new_names, @pirate.reload.send(@association_name).map(&:name) + end + def test_should_automatically_validate_the_associated_models @pirate.send(@association_name).each { |child| child.name = '' } @@ -347,7 +367,9 @@ module AutosaveAssociationOnACollectionAssociationTests def test_should_not_load_the_associated_models_if_they_were_not_loaded_yet assert_queries(1) { @pirate.catchphrase = 'Arr'; @pirate.save! } - assert_queries(2) do + @pirate.send(@association_name).class # hack to load the target + + assert_queries(3) do @pirate.catchphrase = 'Yarr' new_names = ['Grace OMalley', 'Privateers Greed'] @pirate.send(@association_name).each_with_index { |child, i| child.name = new_names[i] } -- 1.5.5.3