October 17, 2008
Who Done What? a.k.a. User Stamping
Something I do in every app I create is add creator_id and updater_id to nearly every model. As created_at and updated_at are known as timestamping, I refer to my creator and updater attributes as “user stamping.” The annoying part is in every controller I had to assign those attributes to the currently logged in user. This isn’t a big deal but I’m lazy so I started to look for solutions.
The first thing that popped into my head was
Thread.current is basically a hash that allows you to assign thread-safe key value pairs for the current thread. My thought, based on some research, was to wrap
User.current so I could just use
User.current in any active record model. Only problem is that smelled a little bit and I figured would be frowned upon by the community as you really shouldn’t access request stuff in your models like that. You can read more about threads and Thread.current if you want.
I brainstormed a bit with Brandon Keepers and he suggested a few things. Eventually, we decided on a sweeper as they have access to controllers which would have access to the current user. Tada! User Stamp, the plugin, was born. I whipped it together last night (< 50 LOC), added a few specs, and put it up on github this morning.
Installation is uber predictable.
script/plugin install git://github.com/jnunemaker/user_stamp.git
Once plugin is installed and user_stamp call with list of models to track in application.rb.
class ApplicationController < ActionController::Base user_stamp Post, Asset, Job end
If you actually want to access this stuff through associations and show it in your app you could do something like this:
class Post < ActiveRecord::Base belongs_to :creator, :class_name => 'User' belongs_to :updater, :class_name => 'User' end
Then, say in a view, you could do the following:
<h1><%=h @post.name %></h1> <div><%= @post.content %></div> <p>Posted by <%=h @post.creator.name %></p>
Let me know what you think in the comments. Bugs can be reported in lighthouse.