mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #41990 from p8/autosave-association-callbacks-get-called-once
Ensure has_one autosave association callbacks get called once
This commit is contained in:
commit
f02a136f89
3 changed files with 59 additions and 1 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
* Ensure `has_one` autosave association callbacks get called once.
|
||||||
|
|
||||||
|
Change the `has_one` autosave callback to be non cyclic as well.
|
||||||
|
By doing this the autosave callback are made more consistent for
|
||||||
|
all 3 cases: `has_many`, `has_one`, and `belongs_to`.
|
||||||
|
|
||||||
|
*Petrik de Heus*
|
||||||
|
|
||||||
* Add option to disable joins for associations.
|
* Add option to disable joins for associations.
|
||||||
|
|
||||||
In a multiple database application, associations can't join across
|
In a multiple database application, associations can't join across
|
||||||
|
|
|
@ -196,7 +196,7 @@ module ActiveRecord
|
||||||
after_create save_method
|
after_create save_method
|
||||||
after_update save_method
|
after_update save_method
|
||||||
elsif reflection.has_one?
|
elsif reflection.has_one?
|
||||||
define_method(save_method) { save_has_one_association(reflection) } unless method_defined?(save_method)
|
define_non_cyclic_method(save_method) { save_has_one_association(reflection) }
|
||||||
# Configures two callbacks instead of a single after_save so that
|
# Configures two callbacks instead of a single after_save so that
|
||||||
# the model may rely on their execution order relative to its
|
# the model may rely on their execution order relative to its
|
||||||
# own callbacks.
|
# own callbacks.
|
||||||
|
|
|
@ -87,6 +87,56 @@ class TestAutosaveAssociationsInGeneral < ActiveRecord::TestCase
|
||||||
assert_predicate r, :valid?
|
assert_predicate r, :valid?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_autosave_collection_association_callbacks_get_called_once
|
||||||
|
ship_with_saving_stack = Class.new(Ship) do
|
||||||
|
def save_collection_association(reflection)
|
||||||
|
@count ||= 0
|
||||||
|
@count += 1 if reflection.name == :parts
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ship = ship_with_saving_stack.new(name: "Nights Dirty Lightning")
|
||||||
|
ship.parts.build(name: "part")
|
||||||
|
ship.save!
|
||||||
|
assert_equal 1, ship.instance_variable_get(:@count)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_autosave_has_one_association_callbacks_get_called_once
|
||||||
|
# a bidirectional autosave is required to trigger multiple calls to
|
||||||
|
# save_has_one_association
|
||||||
|
assert Ship.reflect_on_association(:pirate).options[:autosave]
|
||||||
|
assert Pirate.reflect_on_association(:ship).options[:autosave]
|
||||||
|
|
||||||
|
pirate_with_saving_stack = Class.new(Pirate) do
|
||||||
|
def save_has_one_association(reflection)
|
||||||
|
@count ||= 0
|
||||||
|
@count += 1 if reflection.name == :ship
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pirate = pirate_with_saving_stack.new(catchphrase: "Aye")
|
||||||
|
pirate.build_ship(name: "Nights Dirty Lightning")
|
||||||
|
pirate.save!
|
||||||
|
assert_equal 1, pirate.instance_variable_get(:@count)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_autosave_belongs_to_association_callbacks_get_called_once
|
||||||
|
ship_with_saving_stack = Class.new(Ship) do
|
||||||
|
def save_belongs_to_association(reflection)
|
||||||
|
@count ||= 0
|
||||||
|
@count += 1 if reflection.name == :pirate
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ship = ship_with_saving_stack.new(name: "Nights Dirty Lightning")
|
||||||
|
ship.build_pirate(catchphrase: "Aye")
|
||||||
|
ship.save!
|
||||||
|
assert_equal 1, ship.instance_variable_get(:@count)
|
||||||
|
end
|
||||||
|
|
||||||
def test_should_not_add_the_same_callbacks_multiple_times_for_has_one
|
def test_should_not_add_the_same_callbacks_multiple_times_for_has_one
|
||||||
assert_no_difference_when_adding_callbacks_twice_for Pirate, :ship
|
assert_no_difference_when_adding_callbacks_twice_for Pirate, :ship
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue