Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: Fix false autosave for has_one :through association #35683

Merged
merged 1 commit into from Mar 23, 2019

Conversation

Kukunin
Copy link
Contributor

@Kukunin Kukunin commented Mar 20, 2019

Summary

Fixes #35680

Other Information

The problem occurred, when a has one through association contains a foreign key (it belongs to the intermediate association).

For example, Comment belongs to Post, Post belongs to Author, and Author has_one :first_comment, through: :first_post.

In this case, the value of the foreign key is comparing with the original record, and since they are likely different, the association is marked as changed. So it updates every time when the origin record updates.

@Kukunin Kukunin changed the title BUG: Fix false autosave for has_one :through association Bugfix: Fix false autosave for has_one :through association Mar 20, 2019
@Kukunin
Copy link
Contributor Author

Kukunin commented Mar 20, 2019

How can this be backported to 5.2.x branch?

Copy link
Member

@eileencodes eileencodes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing @Kukunin - please don't backport until we have decided whether to merge this PR. Once merged we will backport or ask you to open a new PR if there are conflicts with the backport.

I restarted the travis build because there were a lot of broken builds but they seemed related to some problem with travis and not here - but also meant it couldn't verify the tests passed.

I also left a few comments but otherwise this is looking good 👍

activerecord/lib/active_record/autosave_association.rb Outdated Show resolved Hide resolved
activerecord/lib/active_record/autosave_association.rb Outdated Show resolved Hide resolved
@Kukunin
Copy link
Contributor Author

Kukunin commented Mar 21, 2019

@eileencodes does it look good now?

end

def _association_foreign_key_changed?(reflection, record, key)
return false if reflection.through_reflection
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use through_reflection?.

Suggested change
return false if reflection.through_reflection
!reflection.through_reflection? &&
record.has_attribute?(reflection.foreign_key) && record[reflection.foreign_key] != key

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dared to leave this as is. Comparing with the other case, where are 3 guards, here is only one.
And mentally things are different enough to not join them into a single complex condition phrase. I consider this as a mentally easier, however less concise

@Kukunin
Copy link
Contributor Author

Kukunin commented Mar 22, 2019

@kamipo @eileencodes so we got a conflict on condition form:

return true if some_condition_A
return true if some_condition_B
return true if some_extremely_long_condition_C

false

or

some_condition_A ||
 some_condition_B ||
 some_extremely_long_condition_C

Which one should I use in this PR?

@kamipo
Copy link
Member

kamipo commented Mar 22, 2019

We usually don’t use multiple early returning.

By extracted a little complex condition, this is already simple enough.
Just use a || b || c

@kamipo kamipo closed this Mar 22, 2019
@kamipo kamipo reopened this Mar 22, 2019
Fixes rails#35680

The problem occurred, when a `has one through` association contains
a foreign key (it belongs to the intermediate association).

For example, Comment belongs to Post, Post belongs to Author, and Author
`has_one :first_comment, through: :first_post`.

In this case, the value of the foreign key is comparing with the original
record, and since they are likely different, the association is marked
as changed. So it updates every time when the origin record updates.
Copy link
Member

@kamipo kamipo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.
Can you squash your commits into one?

@Kukunin
Copy link
Contributor Author

Kukunin commented Mar 23, 2019

Can’t you merge squashed? GitHub supports this feature. If no, I’ll squash it in a couple of hours

@Kukunin
Copy link
Contributor Author

Kukunin commented Mar 23, 2019

squashed, ready to merge

@kamipo kamipo merged commit 430b841 into rails:master Mar 23, 2019
kamipo added a commit that referenced this pull request Mar 26, 2019
Bugfix: Fix false autosave for has_one :through association
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants