Friday, February 21, 2014

Puts'ing/Logging all ActiveRecord Callbacks in All Models in Rails

Sometimes it is helpful in test_helper or wherever to start puts'ing/logging all (or some) ActiveRecord callbacks.

The following loads all models in a Rails app (if it can) and adds callbacks to puts that they were called. Not perfect, but works enough for this example. Try putting this into an initializer, e.g. config/initializers/001_log_callbacks.rb:

# Log all callbacks
Dir[Rails.root.join('app/models/*.rb').to_s].each do |filename|
  name = File.basename(filename, '.rb')
  begin
    model = name.camelize.constantize
    ActiveRecord::Callbacks::CALLBACKS.each do |callback|
      if callback.to_s.start_with?('around_')
        model.class_eval "#{callback} do |*args, &prc|; puts \"#{model}(\#{id}).#{callback} start\"; prc.call(*args) if prc; puts \"#{model}(\#{id}).#{callback} end\" end"
      else
        model.class_eval "#{callback} do; puts \"#{model}(\#{id}).#{callback}\" end"
      end
    end
  rescue
  end
end

Note that this is loading all models directly under app/models/ so you might not want to use this for more than temporary debugging.

No comments: