Make inversed association stale after updating id #43448
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Prior to this commit an inversed association would always return false for
stale_target?
. This could cause problems when updating ids. For example, assuming that thePost#comments
association has an inverse to theComment#post
association:This commit adds a test to catch this example, as well as a test for counter caches (we already test that this counter cache behavior works when
inverse_of
is not set, but wheninverse_of
was set we'd increment and decrement the counter on the same target, effectively a no-op).Solution
This commit updates the
stale_target?
method so it no longer checks whether the association is inversed. That is enough to get the two new tests passing.The
@inversed
check was originally added in #9499, but the test from that PR still passes when we remove@inversed
because of #31214. Rather than tracking@inversed
, we set the inverse when autosaving the has one association, updating the@stale_state
in the process.Removing
@inversed
broke some other tests, however:All of these followed the same pattern of building a record, setting an inverse to the new record, and then saving. For example:
First Rails builds the invoice. Then it sets that new invoice as the inverse for the
line_item
's#invoice
association (i.e. soline_item.invoice
is the same object asinvoice
). Setting the inverse also involves updating@stale_state
, but since it's a new invoice that will benil
. Then everything gets saved, at which point thenil
@stale_state
no longer matchesstale_state
.Rather than relying on
@inversed
to fix this, instead this commit takes a similar approach to #31214 (setting the inverse when autosaving has_one associations) and sets the inverse when autosaving has_many associations. That way we update@stale_state
after the owner is saved and has an id available.