# \[ANN\] Userstamp Plugin

**URL:** <https://www.ruby-forum.com/t/ann-userstamp-plugin/63576>\
**Category:** Rails\
**Created:** [January 21, 2006, 12:53am UTC](https://www.ruby-forum.com/t/ann-userstamp-plugin/63576 "2006-01-21T00:53:44Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![DeLynn\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/bbce88/32.png) [@DeLynn\_B](https://www.ruby-forum.com/u/DeLynn_B)\
**Post date:** [January 21, 2006, 12:53am UTC](https://www.ruby-forum.com/t/ann-userstamp-plugin/63576/1 "2006-01-21T00:53:44Z")

</div>

I’m pleased to announce a new plugin for Rails: Userstamp. You can read  
my  
blog post at  
[http://www.delynnberry.com/articles/2006/01/20/userstamp-plugin](http://www.delynnberry.com/articles/2006/01/20/userstamp-plugin)  
and/or read all about it at the perminant page  
[http://www.delynnberry.com/pages/userstamp](http://www.delynnberry.com/pages/userstamp). Any comments or suggestions  
for  
improvement are much appreciated.

–  
DeLynn B.  
removed\_email\_address@domain.invalid

> **[DeLynn Berry](https://delynnberry.com/)**

A dump of the Readme file is contained below

# – Userstamp Plugin (v 1.0)

## Overview

The Userstamp Plugin extends ActiveRecord::Base(  
[Peak Obsession](http://api.rubyonrails.com/classes/ActiveRecord/Base.html)) to add  
automatic  
updating of created\_by and updated\_by attributes of your models in much  
the  
same way that the ActiveRecord::Timestamp(  
[Peak Obsession](http://api.rubyonrails.com/classes/ActiveRecord/Timestamp.html)) module  
updates created\_(at/on) and updated\_(at/on) attributes.

The module requires that your application’s user object (User by  
default)  
contains an accessor called current\_user be set with an instance of the  
currently logged in user (typically using a before\_filter(  
[Peak Obsession](http://api.rubyonrails.com/classes/ActionController/Filters/ClassMethods.html#M000127)).  
This module can also be turned off on a case by case basis by setting  
the  
record\_userstamps attribute of your ActiveRecord object to false.

## Installation

To install the Userstamp plugin into a current Rails application run the  
script/plugin script from the root of your application passing it the  
url of  
[http://www.delynnberry.com/svn/code/rails/plugins/userstamp/](http://www.delynnberry.com/svn/code/rails/plugins/userstamp/). For  
example:

```
 script/plugin install

```

[http://www.delynnberry.com/svn/code/rails/plugins/userstamp](http://www.delynnberry.com/svn/code/rails/plugins/userstamp)

Once installed you will need to restart your webserver for the plugin to  
be  
loaded into the Rails environment.

## Usage

Here is a simple example for how to use the Userstamp plugin. First,  
create  
a User model object (either using the generator or manually creating the  
file). Adjust your model to include the current\_user accessor like so:

```
 class User < ActiveRecord::Base
     cattr_accessor :current_user
 end

```

Second, create another table and model that will use the Userstamp  
functionality (I’m using Post for this example). Be sure to add the  
created\_by and updated\_by columns to your table definition and also  
create a  
belongs\_to relationship. For example:

```
 class Post < ActiveRecord::Base
     belongs_to :created_by, :class_name => "User", :foreign_key =>

```

“created\_by”  
belongs\_to :updated\_by, :class\_name =\> “User”, :foreign\_key =\>  
“updated\_by”  
end

Then in your ApplicationController create a before\_filter to  
automatically  
set the current\_user:

```
 class ApplicationController < ActionController::Base
     before_filter do |c|
        User.current_user = User.find(c.session[:user].id) unless

```

c.session[:user].nil?  
end  
end

## Uninstall

Uninstalling is simply a matter of running script/plugin from the root  
of  
your Rails application. Except this time you pass the uninstall  
parameter:

```
 script/plugin unistall userstamp

```

## Documentation

RDoc has been run on the plugin directory and is available in the  
download.

## Running Unit Tests

There are extensive unit tests in the “test” directory of the plugin.  
Currently, only MySQL is supported, but  
you should be able to easily fix this by looking at “connection.rb”.  
You’ll  
need to create a  
database for the tests and put the connection information into "  
connection.rb" as well as import the schema file  
for MySQL that can be found at “test/fixtures/mysql.sql”.

To run the test simply execute the follow from the test directory inside  
the  
Userstamp plugin directory:

```
 ruby userstamp_test.rb

```

## Bugs & Feedback

Bug reports and feedback are always welcome. Please send them to  
removed\_email\_address@domain.invalid with [Userstamp] in the subject line.  
You can also visit (  
[http://www.delynnberry.com/articles/category/userstamp/](http://www.delynnberry.com/articles/category/userstamp/))  
and post a comment on any of the posts.

Credits and Special Thanks

---

<div class="post-metadata">

**Author:** ![DeLynn\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/bbce88/32.png) [@DeLynn\_B](https://www.ruby-forum.com/u/DeLynn_B)\
**Post date:** [January 21, 2006, 1:02am UTC](https://www.ruby-forum.com/t/ann-userstamp-plugin/63576/2 "2006-01-21T01:02:47Z")

</div>

Thx for not naming it ActiveStamp … 😉 All joking aside I have your  
early  
version running in my app, and it works as described.

Thx,

~ Ben

---

<div class="post-metadata">

**Author:** ![DeLynn\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/bbce88/32.png) [@DeLynn\_B](https://www.ruby-forum.com/u/DeLynn_B)\
**Post date:** [January 21, 2006, 1:11am UTC](https://www.ruby-forum.com/t/ann-userstamp-plugin/63576/3 "2006-01-21T01:11:52Z")

</div>

> ```
> class Post < ActiveRecord::Base
> belongs_to :created_by, :class_name => "User", :foreign_key =>
> 
> ```
> 
> “created\_by”  
> belongs\_to :updated\_by, :class\_name =\> “User”, :foreign\_key =\>  
> “updated\_by”  
> end

Why created\_by/updated\_by? Why not creator/updater?

@post.created\_by.login

vs

@post.creator.login

–  
Rick O.  
[http://techno-weenie.net](http://techno-weenie.net)

---

<div class="post-metadata">

**Author:** ![DeLynn\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/bbce88/32.png) [@DeLynn\_B](https://www.ruby-forum.com/u/DeLynn_B)\
**Post date:** [January 21, 2006, 1:17am UTC](https://www.ruby-forum.com/t/ann-userstamp-plugin/63576/4 "2006-01-21T01:17:54Z")

</div>

belongs\_to :creator, :class\_name =\> “User”,  
:foreign\_key  
=\> “created\_by”  
belongs\_to :updater, :class\_name =\> “User”,  
:foreign\_key  
=\> “updated\_by”

I think the goal was to follow existing conventions, created\_on,  
updated\_on,  
etc…

~ Ben

---

<div class="post-metadata">

**Author:** ![DeLynn\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/bbce88/32.png) [@DeLynn\_B](https://www.ruby-forum.com/u/DeLynn_B)\
**Post date:** [January 21, 2006, 2:57am UTC](https://www.ruby-forum.com/t/ann-userstamp-plugin/63576/5 "2006-01-21T02:57:27Z")

</div>

On 1/20/06, DeLynn B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Rick,
> 
> The primary reason for choosing the created\_by and updated\_by column  
> names was primarily to follow Timestamp’s created\_(at/on)  
> updated\_(at/on) naming convention.
> 
> Like Ben stated, you can call the relationship “name” whatever you  
> want when you set it up in your model.

Well, I prefer to follow the conventions rails has for associations  
instead. I was just making an observation though. Have fun.

–  
Rick O.  
[http://techno-weenie.net](http://techno-weenie.net)

---

<div class="post-metadata">

**Author:** ![DeLynn\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/bbce88/32.png) [@DeLynn\_B](https://www.ruby-forum.com/u/DeLynn_B)\
**Post date:** [January 21, 2006, 4:09am UTC](https://www.ruby-forum.com/t/ann-userstamp-plugin/63576/6 "2006-01-21T04:09:46Z")

</div>

Rick O. wrote:

> > The primary reason for choosing the created\_by and updated\_by column  
> > names was primarily to follow Timestamp’s created\_(at/on)  
> > updated\_(at/on) naming convention.
> > 
> > Like Ben stated, you can call the relationship “name” whatever you  
> > want when you set it up in your model.
> 
> Well, I prefer to follow the conventions rails has for associations  
> instead. I was just making an observation though. Have fun.

There’s an idea. Since this is a plugin, why not add a class method  
which expresses the relationship better and adds the functionality to  
the model. Something like this:

class Post \< ActiveRecord::Base  
owned\_by :user  
end

It could wrap the belongs\_to calls. And perhaps the stuff for the user  
class could be put in a class method too:

class User \< ActiveRecord::Base  
acts\_as\_user  
end

Wow. Very nice. This would clean things up quite a bit. Maybe you could  
even figure out a way to remove the before filter from the Application  
class as well.

–  
John L.  
[http://wiseheartdesign.com](http://wiseheartdesign.com)

---

<div class="post-metadata">

**Author:** ![DeLynn\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/bbce88/32.png) [@DeLynn\_B](https://www.ruby-forum.com/u/DeLynn_B)\
**Post date:** [January 21, 2006, 10:38am UTC](https://www.ruby-forum.com/t/ann-userstamp-plugin/63576/7 "2006-01-21T10:38:57Z")

</div>

I had done something like that. You have to love easy metaprogramming.

module ActiveRecord

module Userstamp…

class Base  
include Userstamp

```
class << self
  # Allows class declaration of creating association
  # creates :foos
  # Automatically creates #created_foos which use
  # a 'creator_id' foreign key.
  def creates( *args )
    created_symbols = ( 'created_' + args[0].to_s ).to_sym
    created_class = args[0].to_s.singularize.camelize
    created_hash = { :foreign_key => 'creator_id', :class_name =>

```

created\_class }  
created\_hash.merge( args[1] ) if args[1].is\_a?( Hash )  
has\_many created\_symbols, created\_hash  
end

```
  def created_by( *args )
    creator_symbol = args[0]
    creator_hash = { :foreign_key => 'creator_id', :class_name => 

```

‘User’  
}  
creator\_hash.merge( args[1] ) if args[1].is\_a?( Hash )  
belongs\_to creator\_symbol, creator\_hash  
end  
end  
end  
end

I use ‘creator\_id’ instead of created\_by for the table field. The above  
code  
makes the association look more beautiful.

class User \< ActiveRecord::Base  
creates :documents  
has\_many :documents

creates :programs  
end

class Document \< ActiveRecord::Base  
created\_by :creator  
end

Note that in this example a user is the creator of documents as well as  
the  
owner of documents. A user with privileges, like a moderator, could  
create  
documents but might not actually own the documents.  
-Bill

---

<div class="post-metadata">

**Author:** ![DeLynn\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/bbce88/32.png) [@DeLynn\_B](https://www.ruby-forum.com/u/DeLynn_B)\
**Post date:** [January 21, 2006, 2:33am UTC](https://www.ruby-forum.com/t/ann-userstamp-plugin/63576/8 "2006-01-21T02:33:16Z")

</div>

Rick,

The primary reason for choosing the created\_by and updated\_by column  
names was primarily to follow Timestamp’s created\_(at/on)  
updated\_(at/on) naming convention.

Like Ben stated, you can call the relationship “name” whatever you  
want when you set it up in your model.

–  
DeLynn B.  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![DeLynn\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/bbce88/32.png) [@DeLynn\_B](https://www.ruby-forum.com/u/DeLynn_B)\
**Post date:** [January 24, 2006, 1:37pm UTC](https://www.ruby-forum.com/t/ann-userstamp-plugin/63576/9 "2006-01-24T13:37:59Z")

</div>

#if delynn /\* Jan 20, 04:15 \*/

> I’m pleased to announce a new plugin for Rails: Userstamp. You can  
> read my blog post at  
> [1][http://www.delynnberry.com/articles/2006/01/20/userstamp-plugin](http://www.delynnberry.com/articles/2006/01/20/userstamp-plugin)  
> and/or read all about it at the perminant page  
> [2][http://www.delynnberry.com/pages/userstamp](http://www.delynnberry.com/pages/userstamp) . Any comments or  
> suggestions for improvement are much appreciated.  
> #endif /\* removed\_email\_address@domain.invalid \*/

Hi there,  
Great plugin, not sure if you have seen [0]usermonitor.rb but it does a  
similar thing, albeit not as a module. One thing i had to hunt around  
for, in order to make your plugin work, was overriding the User Class.  
I’m storing them in People/Person, this was accomplished by the  
following in environment.rb:

ActiveRecord::Base.user\_model\_name = ‘Person’

Being a newbie to ruby/rails I’m not 100% certain this is the “correct”  
way of achieving this, but it worked for me.

HTH anyone having the same problem.  
-v

[0] [http://rubyurl.com/JLA](http://rubyurl.com/JLA)

–  
keys: [http://codex.net/gpg.asc](http://codex.net/gpg.asc)

An honest politician is one who when he is bought will stay bought.  
– Simon Cameron
