diff --git a/lib/activerecord/delay_touching.rb b/lib/activerecord/delay_touching.rb index f77d33a..a862df3 100644 --- a/lib/activerecord/delay_touching.rb +++ b/lib/activerecord/delay_touching.rb @@ -86,7 +86,7 @@ def self.touch_records(attr, klass, records) column = column.to_s changes[column] = current_time records.each do |record| - next if record.destroyed? + next unless record.persisted? # A new record may have been rolled back record.instance_eval do write_attribute column, current_time @changed_attributes.except!(*changes.keys) @@ -94,10 +94,15 @@ def self.touch_records(attr, klass, records) end end - klass.unscoped.where(klass.primary_key => records).update_all(changes) + updatable_records = records.select{|r| r.persisted?} # No need to touch unpersisted records + + if updatable_records.present? + klass.unscoped.where(klass.primary_key => updatable_records).update_all(changes) + end end state.updated attr, records records.each do |record| + next unless record.persisted? # A new record may have been rolled back record.run_callbacks(:touch) if klass.connection.open_transactions > 0 klass.connection.add_transaction_record record diff --git a/lib/activerecord/delay_touching/state.rb b/lib/activerecord/delay_touching/state.rb index 6d82f19..1d53a96 100644 --- a/lib/activerecord/delay_touching/state.rb +++ b/lib/activerecord/delay_touching/state.rb @@ -15,6 +15,13 @@ def initialize end def updated(attr, records) + # Records may have been changed since they were added to the set. For instance, if an error + # occurred and a Rollback was generated, Rails might change the record's id from an integer + # to a nil (if it's a new record). Since it was stored in the set originally, using the + # hash of the id of the record (thanks to Rails' magic), it won't be removed because now the + # hash is different and it isn't found in the set. + @records[attr] = Set.new(@records[attr]) # recreate the Set so it's reliable + @records[attr].subtract records @records.delete attr if @records[attr].empty? @already_updated_records[attr] += records