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.
|
||||
|
||||
*kennyj*
|
||||
|
|
|
@ -25,9 +25,8 @@ module ActiveRecord
|
|||
raise_on_type_mismatch!(record) if record
|
||||
load_target
|
||||
|
||||
# If target and record are nil, or target is equal to record,
|
||||
# we don't need to have transaction.
|
||||
if (target || record) && target != record
|
||||
return self.target if !(target || record)
|
||||
if (target != record) || record.changed?
|
||||
transaction_if(save) do
|
||||
remove_target!(options[:dependent]) if target && !target.destroyed?
|
||||
|
||||
|
|
|
@ -522,4 +522,20 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
|||
account = Account.find(2)
|
||||
assert_queries { company.account = account }
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue