[ANN] Userstamp Plugin


#1

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
and/or read all about it at the perminant page
http://www.delynnberry.com/pages/userstamp. Any comments or suggestions
for
improvement are much appreciated.


DeLynn B.
removed_email_address@domain.invalid

A dump of the Readme file is contained below


Userstamp Plugin (v 1.0)

Overview

The Userstamp Plugin extends ActiveRecord::Base(
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(
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(
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/. For
example:

 script/plugin install

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/)
and post a comment on any of the posts.

Credits and Special Thanks


#2

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

Thx,

~ Ben


#3
  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


#4

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


#5

On 1/20/06, DeLynn B. 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


#6

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


#7

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


#8

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


#9

#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
and/or read all about it at the perminant page
[2]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


keys: http://codex.net/gpg.asc

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