CodedAttribute

Two of my favorite MySQL datatypes are ENUMs and SETs. Unfortunately, ActiveRecord doesn’t appear to support these fields well, or provide a good and simple alternative to the problem of coded values. In the past, I used to write getters and setters that looked something like this to solve my problem.

class Article
  STATUS_CODES => {
      :deleted => 0, 0 => :deleted
      :pending => 1, 1 => :pending,
    :completed => 2, 2 => :completed,
    :published => 3, 3 => :published
  }

  def status=(value)
    value = value.to_sym if value.is_a?(String)
    status_code = STATUS_CODES[value]
  end

  def status
    STATUS_CODES[status_code]
  end
end

Doesn’t that code look horrible? Wouldn’t it be better if it looked like this?!

class Article
  coded_attribute :status {
    0 => :deleted
    1 => :pending
    2 => :completed
    3 => :published
  end
end

Or, if we want to get even lazier!

class MyClass
  coded_attribute :status, [ :deleted, :active, :pending, :deleted ]
end

If so, then you’ve come to the right place.

This plugin makes doing all of the above super easy. And your code (and other programmers) will love you for using it! Like seriously love you!

Coded Attributes

Lets get down to it. Suppose we have a car, and it can be any one of a variety of colors. We can indicate this in the model with the following code:

class Car < ActiveRecord::Base
  coded_attribute :color, [ :red, :orange, :yellow, :green, :blue, :indigo, :violet ]
end

But we aren’t finished just yet. We still need to create a column to store our attribute data in. There are two ways to go about this.

Storing the Coded Value

The easiest way to store the coded value is to create an integer column in the database by appending ‘_code’ to the name of the attribute. So in our ‘cars’ table, we could create a ‘color_code’ integer field. If you do not want to name the column in your database ‘color_code’, you can replace :color, with a :method => :column pair, for example:

class Car < ActiveRecord::Base
  coded_attribute :color => :color_id, [ :red, orange, :yellow, :green, :blue, :indigo, :violet ]
end

Coded Attribute Sets

If you do not want to use a SET datatype, coded_attribute_set an make use of an integer bitmask to store the values.

class Car < ActiveRecord::Base
  coded_attribute_set :color, [ :red, :orange, :yellow, :green, :blue, :indigo, :violet ]
end

Planned Features

Future versions should hopefully support auto-detecting and setup of enum and set types (so you don’t need to even define the coded_attribute, it will be done automatically on all classes).

I also plan on a method added to Migrations that allow you to easily recode data

Copyright © 2010 Jaden Carver, released under the MIT license