Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

save on parent should not cascade to child unless child changed [#3353

…state:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information...
commit 4a0d7c1a439c6ad8d35bf514761824e51fa07df2 1 parent e210895
@subbarao subbarao authored josevalim committed
View
4 activerecord/lib/active_record/autosave_association.rb
@@ -372,7 +372,9 @@ def save_belongs_to_association(reflection)
if autosave && association.marked_for_destruction?
association.destroy
elsif autosave != false
- saved = association.save(:validate => !autosave) if association.new_record? || autosave
+ if association.new_record? || ( autosave && association.changed? )
+ saved = association.save(:validate => !autosave)
+ end
if association.updated?
association_id = association.send(reflection.options[:primary_key] || :id)
View
18 activerecord/test/cases/autosave_association_test.rb
@@ -632,6 +632,8 @@ def test_a_parent_marked_for_destruction_should_not_be_destroyed_twice
end
def test_should_rollback_destructions_if_an_exception_occurred_while_saving_a_parent
+ #association save method only trigged when association is changed
+ @ship.pirate.catchphrase = "new catch phrase"
# Stub the save method of the @ship.pirate instance to destroy and then raise an exception
class << @ship.pirate
def save(*args)
@@ -880,6 +882,22 @@ def setup
@pirate = @ship.create_pirate(:catchphrase => "Don' botharrr talkin' like one, savvy?")
end
+ def test_should_not_call_belongs_to_after_save_callbacks_if_no_changes
+ @ship.attributes = { :name => "Titanic", :pirate_attributes => {:id => @pirate.id} }
+ #here there are no changes to pirate so if save on ship causes save on pirate
+ #this callback will fail pirate save.(pirate save shouldn't happen)
+ @ship.pirate.cancel_save_from_callback = true
+ @ship.save
+ assert_equal 'Titanic', @ship.reload.name
+ end
+
+ def test_should_call_belongs_to_save_if_belongs_to_has_changes
+ @ship.attributes = { :name => "Titanic", :pirate_attributes => { :catchphrase => 'Jack', :id => @pirate.id} }
+ @ship.save
+ assert_equal 'Titanic', @ship.reload.name
+ assert_equal 'Jack', @pirate.reload.catchphrase
+ end
+
def test_should_still_work_without_an_associated_model
@pirate.destroy
@ship.reload.name = "The Vile Insanity"
Please sign in to comment.
Something went wrong with that request. Please try again.