module ActivityLogger extend ActiveSupport::Concern included do [["create", "created"], ["update", "updated"], ["destroy", "destroyed"]].each do |meth, action| if respond_to?("after_#{meth}") send("after_#{meth}", -> { log_activity(action) }) end end end protected def activity_data respond_to?(:saved_changes) && saved_changes.any? ? {changes: saved_changes.except("created_at", "updated_at")} : {} end def activity_attributes attributes.slice("id", "name") end def log_activity(action, data: nil) data ||= activity_attributes.merge(activity_data) # This assumes Current.user is set in a controller, but it will work without it ActiveSupport::Notifications.instrument("activity", {event: "#{action}-#{model_name.singular}", user_id: Current.user&.id, data: data}) end end