Skip to content
This repository was archived by the owner on Jan 27, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion activerecord-delay_touching.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]

spec.add_dependency "activerecord", "~> 4.2"
spec.add_dependency "activerecord", ">= 4.2", "< 5.3"

spec.add_development_dependency "bundler", "~> 1.6"
spec.add_development_dependency "rake"
Expand Down
37 changes: 27 additions & 10 deletions lib/activerecord/delay_touching.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ module DelayTouching
extend ActiveSupport::Concern

# Override ActiveRecord::Base#touch.
def touch(*names)
if self.class.delay_touching? && !try(:no_touching?)
DelayTouching.add_record(self, *names)
true
else
super
if ActiveRecord::VERSION::MAJOR >= 5
def touch(*names, time: nil)
names = self.class.send(:timestamp_attributes_for_update_in_model) if names.empty?
Copy link

@oehlschl oehlschl Jan 22, 2019

Choose a reason for hiding this comment

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

FYI @Kenneth-KT, these changes failed for us locally on Rails v5.0.7 with the following error:

NoMethodError:
  undefined method `timestamp_attributes_for_update_in_model' for #<Class:0x00007fbcde0ace48>

(To clarify, we're in the process of upgrading an application that currently uses DelayTouching from Rails 4.2 to 5.0.)

From the source, it looks like even through v5.2.2, this method is accessed on the instance, not class, level:
https://github.com/rails/rails/blob/v5.0.7/activerecord/lib/active_record/touch_later.rb#L18
https://github.com/rails/rails/blob/v5.2.2/activerecord/lib/active_record/touch_later.rb#L20

We're now using the following instead:

self.send(:timestamp_attributes_for_update_in_model) if names.empty?

Choose a reason for hiding this comment

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

Also, I'm admittedly not familiar with the Rails 5 persistence implementation, but what's the need for timestamp_attributes_for_update_in_model here?

It seems like a nil value is expected in the case of only touching defaults, and is handled here:

DelayTouching.handle_touch(self, names) || super
end
else
def touch(*names)
DelayTouching.handle_touch(self, names) || super
end
end

Expand Down Expand Up @@ -45,6 +47,13 @@ class << self
delegate :add_record, to: :state
end

def self.handle_touch(record, names)
if record.class.delay_touching? && !record.try(:no_touching?)
add_record(record, *names)
true
end
end

# Start delaying all touches. When done, apply them. (Unless nested.)
def self.call
state.nesting += 1
Expand Down Expand Up @@ -88,10 +97,8 @@ def self.touch_records(attr, klass, records)
records.each do |record|
# Don't bother if destroyed or not-saved
next unless record.persisted?
record.instance_eval do
write_attribute column, current_time
@changed_attributes.except!(*changes.keys)
end
record.send(:write_attribute, column, current_time)
clear_attribute_changes(record, changes.keys)
end
end

Expand All @@ -100,6 +107,16 @@ def self.touch_records(attr, klass, records)
state.updated attr, records
records.each { |record| record.run_callbacks(:touch) }
end

if ActiveRecord::VERSION::MAJOR >= 5
def self.clear_attribute_changes(record, attr_names)
record.clear_attribute_changes(attr_names)
end
else
def self.clear_attribute_changes(record, attr_names)
record.instance_variable_get('@changed_attributes').except!(*attr_names)
end
end
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/activerecord/delay_touching/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Activerecord
module DelayTouching
VERSION = "1.1.0"
VERSION = "1.1.1"
end
end