Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Also save :autosave enabled associations when #save! is used.

Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#1877 state:committed]
  • Loading branch information...
commit db5d6950169f8f10b6aec85faa2c38e0c57315c7 1 parent 455a763
@alloy alloy authored NZKoz committed
View
12 activerecord/lib/active_record/autosave_association.rb
@@ -129,6 +129,7 @@ def self.included(base)
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 @@ def save_with_autosave_associations(perform_validation = true)
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, <tt>self</tt>, and any loaded autosave associations are valid.
def valid_with_autosave_associations?
if valid_without_autosave_associations?
View
24 activerecord/test/cases/autosave_association_test.rb
@@ -169,6 +169,12 @@ def test_should_automatically_save_the_associated_model
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 @@ def test_should_automatically_save_the_associated_model
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 @@ def test_should_automatically_save_the_associated_models
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 @@ def test_should_still_raise_an_ActiveRecordRecord_Invalid_exception_if_we_want_t
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] }
Please sign in to comment.
Something went wrong with that request. Please try again.