Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 5fa701ebc9
Fetching contributors…

Cannot retrieve contributors at this time

104 lines (71 sloc) 4.719 kb


Tracktor is a Rails plugin that eases audit logging of actors (creator and updater) for any class that descends from ActiveRecord::Base. The goal is to seamlessly log the actors without needing to explicitly mention them when writing your application code. This is accomplished by storing the current actor in a thread-local variable for the duration of a particular HTTP request (note that this means that Tracktor will not work with multi-threaded application servers).

Any time you create or update a record within the context of a request, an ActiveRecord::Observer takes over and sets the creator and updater automatically. In other words:

# before - app/controllers/books_controller.rb
def create
  @book = Book.create(params[:book].merge(:creator => current_user, :updater => current_user))

# after - app/controllers/books_controller.rb
def create
  @book = Book.create(params[:book])

The simplest setup for Tracktor is as follows:

# app/models/book.rb (repeat with every model class for which you'd like automatic actor tracking)
class Book < ActiveRecord::Base

# db/migrate/001_create_books.rb
class CreateBooks < ActiveRecord::Migration
  def self.up
    create_table :books do |t|

# app/controllers/application.rb
class ApplicationController < ActionController::Base


Tracktor adds an ActiveRecord::Base.track_actors method that sets up automatic actor tracking for the class. By default, Tracktor assumes that the actor's class name is “User”; if this is not the case, you can specify the class name like so:

class Book < ActiveRecord::Base
  track_actors :class_name => "Member"

You can also specify a default actor, which will be used if there is no current actor set:

class Book < ActiveRecord::Base
  track_actors :default => lambda { User.find_by_id(0) }

Specifying track_actors will allow you to reference the creator and updater associations from the object being tracked:

book = Book.create!(:name => "Survivor")
puts book.creator


Tracktor adds an ActiveRecord::Migration#actors method that creates two integer columns: created_by and updated_by. These columns reference the row ids of the actors that created or updated the book.

By default, these columns have not-null constraints (:null => false), but this may be overridden if desired. No foreign keys are created; if you care about that sort of thing, make sure you include it in your migration.


Tracktor adds an ActionController::Base.enable_actor_tracking method, which should be added to application.rb after any before_filter or other code that is responsible for logging users in. This method wraps the request such that the current actor is available to an Observer that watches for record creation or updating.

By default, the enable_actor_tracking method will try to grab the actor by calling the current_user method; this can be overridden like so:

enable_actor_tracking :from => :logged_in_user


Tracktor hearts Test-Driven Development. In fact, Tracktor hearts TDD so much that it adds a Test::Unit::TestCase.test_actor_tracking_for method that can be used like so:

class BookTest < Test::Unit::TestCase
  test_actor_tracking_for :book

This will create and run the following tests:

  • test_creator_association

  • test_updater_association

  • test_creator_should_be_set_to_current_before_validation_on_create

  • test_updater_should_be_set_to_current_before_validation

  • test_creator_should_default_when_current_is_not_set

  • test_updater_should_default_when_current_is_not_set

Any other tests you'd like to write (to test custom class names, etc.) are on you.


There are times when it is necessary to create/update objects that normally track actors when you are outside of the context of an HTTP request (or inside one without a logged in user). For this, Tracktor includes the as_actor method, which can be used like so:

as_actor(User.find_by_id(0)) do
  Book.create!(:name => "Choke")

This can be especially useful when writing tests, command-line scripts, rake tasks, etc. Tracktor adds validations to created_by and updated_by, so an error that states “Updated by can't be blank” will often point to the fact that you are operating outside the context of an HTTP request, and need to use as_actor.

Copyright © 2008 Centro, released under the MIT license. Authored by:

Jump to Line
Something went wrong with that request. Please try again.