Ensure alias resolved before `clear_attribute_changes`

It is a super edge case but the alias should be resolved before
`clear_attribute_changes` since `clear_attribute_changes` is not aware
of attribute aliases.
This commit is contained in:
Ryuta Kamizono 2020-06-04 11:52:35 +09:00
parent 7834363bbf
commit 265234b377
3 changed files with 16 additions and 11 deletions

View File

@ -90,6 +90,7 @@ module ActiveRecord
begin
locking_column = self.class.locking_column
previous_lock_value = read_attribute_before_type_cast(locking_column)
attribute_names = attribute_names.dup if attribute_names.frozen?
attribute_names << locking_column
self[locking_column] += 1

View File

@ -670,11 +670,8 @@ module ActiveRecord
attributes = attributes.transform_keys do |key|
name = key.to_s
self.class.attribute_aliases[name] || name
end
attributes.each_key do |key|
verify_readonly_attribute(key)
name = self.class.attribute_aliases[name] || name
verify_readonly_attribute(name) || name
end
id_in_database = self.id_in_database
@ -857,9 +854,10 @@ module ActiveRecord
_raise_record_not_touched_error unless persisted?
attribute_names = timestamp_attributes_for_update_in_model
attribute_names |= names.map!(&:to_s).map! { |name|
attribute_names |= names.map! do |name|
name = name.to_s
self.class.attribute_aliases[name] || name
}
end unless names.empty?
unless attribute_names.empty?
affected_rows = _touch_row(attribute_names, time)

View File

@ -12,7 +12,11 @@ module ActiveRecord
_raise_record_not_touched_error unless persisted?
@_defer_touch_attrs ||= timestamp_attributes_for_update_in_model
@_defer_touch_attrs |= names unless names.empty?
@_defer_touch_attrs |= names.map! do |name|
name = name.to_s
self.class.attribute_aliases[name] || name
end unless names.empty?
@_touch_time = current_time_from_proper_timezone
surreptitiously_touch @_defer_touch_attrs
@ -38,9 +42,11 @@ module ActiveRecord
end
private
def surreptitiously_touch(attrs)
attrs.each { |attr| write_attribute attr, @_touch_time }
clear_attribute_changes attrs
def surreptitiously_touch(attr_names)
attr_names.each do |attr_name|
_write_attribute(attr_name, @_touch_time)
clear_attribute_change(attr_name)
end
end
def touch_deferred_attributes