Skip to content

Commit

Permalink
Ensure alias resolved before clear_attribute_changes
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kamipo committed Jun 4, 2020
1 parent 7834363 commit 265234b
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 11 deletions.
1 change: 1 addition & 0 deletions activerecord/lib/active_record/locking/optimistic.rb
Expand Up @@ -90,6 +90,7 @@ def _update_row(attribute_names, attempted_action = "update")
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
Expand Down
12 changes: 5 additions & 7 deletions activerecord/lib/active_record/persistence.rb
Expand Up @@ -670,11 +670,8 @@ def update_columns(attributes)

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
Expand Down Expand Up @@ -857,9 +854,10 @@ def touch(*names, time: nil)
_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)
Expand Down
14 changes: 10 additions & 4 deletions activerecord/lib/active_record/touch_later.rb
Expand Up @@ -12,7 +12,11 @@ def touch_later(*names) # :nodoc:
_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
Expand All @@ -38,9 +42,11 @@ def touch(*names, time: nil) # :nodoc:
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
Expand Down

0 comments on commit 265234b

Please sign in to comment.