My Task model has commit callbacks that send notifications. But the task model ALSO gets touched by a bunch of associated/child records, and these really shouldn’t be sending notifications for each one.

I’ve decided to write a simple touch_without_callbacks method that helped me acheive this.

How to touch rails columns without callbacks

create an initializer called touch_without_callbacks.rb

module TouchWithoutCallbacks
  extend ActiveSupport::Concern

  def touch_without_callbacks(\*names, time: nil)
    time ||= current_time_from_proper_timezone

    attribute_names = timestamp_attributes_for_update_in_model
    attribute_names |= names.map(&:to_s)

    return false if attribute_names.empty?

    changes = {}

    attribute_names.each do |attr_name|
      changes[attr_name] = time
    end

    primary_key = self.class.primary_key
    self.class.unscoped.where(primary_key => self[primary_key]).update_all(changes) == 1
  end

  def current_time_from_proper_timezone
    default_timezone == :utc ? Time.now.utc : Time.now
  end
end

# include the extension into your rails models
ActiveRecord::Base.send(:include, TouchWithoutCallbacks)

So now in your rails code, you can do somemthing like this:

task = Task.find(...)
task.touch # will change the `updated_at` column to the current timestamp

task.touch(:reminder_at) # will change both updated_at and reminder_at

some different versions of touch