mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix #8856 Ensure has_one association=(associate) triggers save.
activerecord/lib/active_record/associations.rb states:
# [association=(associate)]
# Assigns the associate object, extracts the primary key, sets it as the foreign key,
# and saves the associate object.
Since commit 42dd5d9f29
to fix #7191, this
is no longer the case if the associate has changed, but is the same
object. For example:
# Pirate has_one :ship
pirate = Pirate.create!(catchphrase: "A Pirate")
ship = pirate.build_ship(name: 'old name')
ship.save!
ship.name = 'new name'
pirate.ship = ship
That last line should trigger a save. Although we are not changing the
association, the associate (ship) has changed.
This commit is contained in:
parent
e8e2f010af
commit
ebd7cc6f45
3 changed files with 24 additions and 3 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
* Trigger a save on `has_one association=(associate)` when the associate contents have changed.
|
||||||
|
|
||||||
|
Fix #8856.
|
||||||
|
|
||||||
|
*Chris Thompson*
|
||||||
|
|
||||||
* Abort a rake task when missing db/structure.sql like `db:schema:load` task.
|
* Abort a rake task when missing db/structure.sql like `db:schema:load` task.
|
||||||
|
|
||||||
*kennyj*
|
*kennyj*
|
||||||
|
|
|
@ -25,9 +25,8 @@ module ActiveRecord
|
||||||
raise_on_type_mismatch!(record) if record
|
raise_on_type_mismatch!(record) if record
|
||||||
load_target
|
load_target
|
||||||
|
|
||||||
# If target and record are nil, or target is equal to record,
|
return self.target if !(target || record)
|
||||||
# we don't need to have transaction.
|
if (target != record) || record.changed?
|
||||||
if (target || record) && target != record
|
|
||||||
transaction_if(save) do
|
transaction_if(save) do
|
||||||
remove_target!(options[:dependent]) if target && !target.destroyed?
|
remove_target!(options[:dependent]) if target && !target.destroyed?
|
||||||
|
|
||||||
|
|
|
@ -522,4 +522,20 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
||||||
account = Account.find(2)
|
account = Account.find(2)
|
||||||
assert_queries { company.account = account }
|
assert_queries { company.account = account }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_has_one_assignment_triggers_save_on_change
|
||||||
|
pirate = Pirate.create!(catchphrase: "Don' botharrr talkin' like one, savvy?")
|
||||||
|
ship = pirate.build_ship(name: 'old name')
|
||||||
|
ship.save!
|
||||||
|
|
||||||
|
ship.name = 'new name'
|
||||||
|
assert ship.changed?
|
||||||
|
assert_queries(2) do
|
||||||
|
# One query for updating name and second query for updating pirate_id
|
||||||
|
pirate.ship = ship
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal 'new name', pirate.ship.reload.name
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue