Skip to content

Instantly share code, notes, and snippets.

@miguelff
Created October 22, 2013 14:26
Show Gist options
  • Save miguelff/7101649 to your computer and use it in GitHub Desktop.
Save miguelff/7101649 to your computer and use it in GitHub Desktop.
# With thanks to https://github.com/optoro/activerecord-callback_notification for original inspiration
if Rails.env.development?
module ActiveRecord
module CallbackNotifications
extend ActiveSupport::Concern
module ClassMethods
def notify_all_callbacks
# Make sure all models are loaded before trying to enumerate
Dir.glob(File.join(Rails.root, 'app/models/*.rb')).each { |file| require file }
ActiveRecord::Base.send(:subclasses).each do |model|
notify_callbacks_for_class(model)
end
end
def notify_callbacks_for_class(klass)
class_instance_methods = klass.public_instance_methods(false) +
klass.protected_instance_methods(false) +
klass.private_instance_methods(false)
[:_create_callbacks, :_update_callbacks, :_save_callbacks].each do |callback_type|
klass.send(callback_type).map(&:filter).each do |callback|
# Ignore callbacks added by Rails
next unless class_instance_methods.include?(callback)
next if callback.to_s =~ /^autosave_/
callback_method = "#{callback}_with_instrumentation"
next if klass.respond_to?(callback_method)
puts "instrumenting #{callback}"
klass.class_eval {
define_method callback_method do |&block|
ActiveSupport::Notifications.instrument("callback:#{callback}",
:object => self,
:callback => callback
)
"#{callback}_without_instrumentation"
end
klass.alias_method_chain callback, :instrumentation
}
end
end
end
end
end
end
ActiveRecord::Base.send(:include, ActiveRecord::CallbackNotifications)
# Set up callback notifications for all models
ActiveRecord::Base.notify_all_callbacks
# Or for individual models
# ActiveRecord::Base.notify_callbacks_for_class(Beverage)
# Subscribe to notifications to show in Rails log
ActiveSupport::Notifications.subscribe(/^callback:/) do |*data|
return unless ActiveRecord::Base.logger.debug?
name = data.first
event_details = data.last
callback_object = event_details[:object]
ActiveRecord::Base.logger.debug " #{name} [ #{callback_object.class} #{callback_object.id} ]"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment