-
Notifications
You must be signed in to change notification settings - Fork 45
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
Prevent touch from saving unsaved changes #148
base: master
Are you sure you want to change the base?
Conversation
ea3d0dc
to
03753e0
Compare
if @_skip_dirty_tracking ||= false | ||
clear_attribute_changes(_touch_attr_names) | ||
return affected_rows | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably this @_skip_dirty_tracking
check is not appropriate. I'll review it later.
See also rails/rails#36271
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, perhaps we need to start with how to define implicit touching by TouchLater
in bi-temporal semantics. There's a long way to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ActiveRecord::TouchLater
seems completely broken in the bi-temporal gem...
Added a comment about the behavior I investigated.
03753e0
to
f77f70c
Compare
# Note that unlike the original, changes must be evacuated and restored. | ||
# As explained above, this is to avoid implementation differences in _update_row. | ||
# | ||
# FIXME: Implicit touching with `touch: true`` is **completely** broken in the bi-temporal gem. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# FIXME: Implicit touching with `touch: true`` is **completely** broken in the bi-temporal gem. | |
# FIXME: Implicit touching with `touch: true` is **completely** broken in the bi-temporal gem. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it looks good.
See also #140
#140 fixes the issue where
touch
generates irrelevant changes by fixing_update_row
. However, I noticed that the currenttouch
implementation has another problem where unsaved changes are saved.The problem lies in the difference in the implementation of
_update_row
:https://github.com/kufu/activerecord-bitemporal/blob/v4.3.0/lib/activerecord-bitemporal/bitemporal.rb#L315
https://github.com/rails/rails/blob/v7.1.0/activerecord/lib/active_record/persistence.rb#L1210
The original implementation only saves the
attribute_names
, whereasActiveRecord::Bitemporal::Persistence
saves all unsaved changes.The
touch
temporarily evacuate unsaved changes inActiveRecord::AttributeMethods::Dirty#_touch_row
. The order in which you call them is important here. In the original, this is done in the following order:ActiveRecord::Persistence#_touch_row
changes
variablehttps://github.com/rails/rails/blob/v7.1.0/activerecord/lib/active_record/attribute_methods/dirty.rb#L203-L222
This works fine when only
attribute_names
are saved, as mentioned above, but it does not work with bitemporalized models.This PR overrides
_touch_row
and changes the order as follows:changes
variableActiveRecord::Bitemporal::Persistence#_update_row
This solves the problem of unintended changes being saved and changes caused by bi-temporal operations remaining.