Clear cached has_one association after setting belongs_to association to nil

Given an author that "has one" post, and setting the post's author to nil,
the author will still have a cached association to the post. Updating any
attribute of the author would erroneously restore the post's author. This
commit resets the association, preventing that behavior.
This commit is contained in:
Michiel de Mare 2021-06-25 14:52:26 +02:00
parent f263530bf7
commit 484303d698
4 changed files with 37 additions and 0 deletions

@ -1,3 +1,12 @@
* Clear cached `has_one` association after setting `belongs_to` association to `nil`.
After setting a `belongs_to` relation to `nil` and updating an unrelated attribute on the owner,
the owner should still return `nil` on the `has_one` relation.
Fixes #42597.
*Michiel de Mare*
* OpenSSL constants are now used for Digest computations.
*Dirkjan Bussink*

@ -77,6 +77,8 @@ def replace(record)
raise_on_type_mismatch!(record)
set_inverse_instance(record)
@updated = true
elsif target
remove_inverse_instance(target)
end
replace_keys(record, force: true)

@ -1205,6 +1205,19 @@ def test_reassigning_the_parent_id_updates_the_object
assert_equal companies(:another_firm), client.firm_with_condition
end
def test_clearing_an_association_clears_the_associations_inverse
author = Author.create(name: "Jimmy Tolkien")
post = author.create_post(title: "The silly medallion", body: "")
assert_equal post, author.post
assert_equal author, post.author
author.update!(post: nil)
assert_nil author.post
post.update!(title: "The Silmarillion")
assert_nil author.post
end
def test_destroying_child_with_unloaded_parent_and_foreign_key_and_touch_is_possible_with_has_many_inversing
with_has_many_inversing do
book = Book.create!

@ -307,6 +307,19 @@ def test_create_association
assert_equal account, firm.reload.account
end
def test_clearing_an_association_clears_the_associations_inverse
author = Author.create(name: "Jimmy Tolkien")
post = author.create_post(title: "The silly medallion", body: "")
assert_equal post, author.post
assert_equal author, post.author
post.update!(author: nil)
assert_nil post.author
author.update!(name: "J.R.R. Tolkien")
assert_nil post.author
end
def test_create_association_with_bang
firm = Firm.create(name: "GlobalMegaCorp")
account = firm.create_account!(credit_limit: 1000)