Active Record and Customization

February 20, 2006

This post by Tim Almond on the Joel on Software forum reminded me that there are some serious perception issues related to Active Record that need to be corrected in the public eye.

For instance, ActiveRecord. It is interesting, but in the end, nowhere I’ve worked has simply wanted a simple “update” for their databases. They typically want some audit information stored.

He’s right, of course, you almost always want to do something more than just store the raw data of a record. You may wish to track who made the updates and when. You may wish to encode some of the information, or verify its validity against some other source. Sadly, Tim goes on to say this:

Nothing out of the box will deliver this, so you are then into thinking about either coding your needs on each instance, or modifying the base code of the framework to run with your default behaviour.

I don’t know which framework he’s talking about, and it doesn’t really matter from the perspective of Tim being wrong, at least about Active Record in the general sense. It may be perfectly true in instances of specific frameworks.

In a generic Active Record solution such as Object Builder the obvious solution is to derive the Active Record objects from a base object that has the behavior you’re interested in. That’s exactly what I’ve done in every instance of Object Builder that I’ve used. On some occasions I’ve gone so far as to have two different, but similar base classes that I derive from. For instance I may need to track the last modification for a significant percentage of my tables, but it could be entirely irrelevant for others. So for tables with fields for this audit table I derive from the base class that tracks this information, and for the other tables I use a different class (an xsl:choose statement based on the presence of a field handles the matter).

For behavior that’s specific to a single table, a custom class is written that descends from that table’s Active Record object. Let’s say that I need to encode user passwords before saving the user records to the database. In my descendent class, in the save operation, I check the password to see if it’s already encrypted using the OS crypt function. Typically an encrypted password will be of a specific length, and will begin with something like $1$. If I don’t find those criteria met, I run the encryption on the presented password, then call the inherited Save method. This, of course, assumes that I’ve done something in my interface code to prevent the user from entering a password that matches these criteria.

I’ll be the first to admit that Active Record isn’t the perfect design solution to every problem. There are certainly areas where it isn’t appropriate. But Active Record is a good deal more flexible than a lot of people give it credit for.

Advertisements

2 Responses to “Active Record and Customization”

  1. Tim Almond Says:

    I must confess to only scraping the surface with ActiveRecord, but I will take a deeper look at it after your posting.

    I am a sceptic about frameworks in general – I’ve seen the results of many “in-house” middleware solutions that turn out to be a complete disaster. I suppose that if the solutions are being used by enough people, that the framework is less likely to have bugs that an in-house solution will.

    Cheers
    Tim

  2. Clay Dowling Says:

    I’m a huge fan of avoiding the architecture astronaut syndrome myself. I’ve seen systems that were so overly elaborate that it was nearly impossible to do anything with them. I’ve also seen large applications that didn’t use any data objects more complex than Borland’s BDE (which is a nightmare to maintain). In fact the first prototype of my Object Builder was designed to replace that system.

    As frameworks go, setting up Active Record objects is pretty small scale. For me it’s principally a convenience to keep from having to write database calls all through my interface or business logic code. I really don’t want to spend my time in the business logic or interface code dealing directly with the database. I’ve been down that road and it wasn’t very pretty.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: