Subvert legacy table schemas with alias_column

Earlier this week I was writing a model class for a table whose schema broke Rails coding convention. Some column names were written in CamelCase, some were way too short, and the naming scheme overall was inconsistent. Here’s some sample code that gives you an idea of what I’m talking about:

<%= text_field 'order', 'BillingAddressLine1' -%>
<%= text_field 'order', 'order_recipient' -%>

Okay, easily taken care of. I’ll just rename the table columns in the database; they were due for a makeover anyways. But what if you can’t? What if there are shell scripts or other web apps that depend on the table definition as-is, and you don’t have the time/budget to change all of them?

And so alias_column was born. It’s a single function that takes a hash of column aliases. I wrapped it up as a plugin because, hey, I’d never built a proper one before.

Here’s our new Order model definition:

class Order
  alias_column :billing1 => :BillingAddressLine1,
               :billing2 => :BillingAddressLine2,
               :credit_card_number => :ccNum

  validates_presence_of :billing1
end

Now you can access those fields just as you would the old ones. Validators, form helpers, and group setters all work fine.

$ ruby script/console
$ Loading development environment.
>> order = Order.new :billing1 => '123 Main St.', :billing2 => 'Unit 101'
=> <Order:...>
>> order.billing1
=> '123 Main St.'
>> order.credit_card_number
=> nil

There’s nothing fancy going on here: alias_column just creates read/write accessors for your column attributes. It does not introduce a second layer of abstraction between ActiveRecord and your table. For example, Order.columns will still return me the original columns and their db-specific connections.

To install the plugin, use the following:

ruby script/plugin install svn://www.benlog.org/pub/plugins/alias_column

Edit: Okay, it turns out this has been done before. But if it’s of any consolation, those solutions don’t make use of that nice hash statement.