Subscribe to
Posts
Comments

Invariably, in almost every application there happen to be lists of data items that are immutable, just for reference. It could be colors, the four seasons, continents, the states of your country, kinds or types of this and that. These items are almost like constants. As accessible as they are through the ordinary ActiveRecord API, it seems an utter waste to hit the database again and again, for data that won’t change however often you request it.

Of course, the Rails community recognized early on that some data are more constant than others and over the years several plugins have been published that add cached and easily accessible enumerations to ActiveRecord. Some of these additions are quite complicated or befuddle ActiveRecord by not backing the enumeration values with real database objects. My experience has been that these attempted optimizations result in bizarre behavior when I did interesting things with ActiveRecord such as multiply nested named scopes plus custom SQL.

So, I thought a basic, no, simplistic, version of enumerations is called for. Here’s how it looks:

class Color < ActiveRecord::Base
  enumerates do |e|
    e.value :name => 'red'
    e.value :name => 'green'
    e.value :name => 'blue'
  end
end

Color[:green]
Color.find_by_name('red')
Color.find_by_name!(:red)
Color.all
Color.count
Color.reload

e.value :name => 'red'

ensures that a Color object with name ‘red’ exists, if it does not, one is created.

Caveats

Although there is a #reload method defined on enumeration models, i.e. Color.reload, it is very unwise to use it. The point is that this method only affects a single server process and you most likely have many of them.

So, if you need to change enumeration values, the only way to do it is to treat it like an update to your application code.

Getting it

  • github
  • $ sudo gem install mschuerig-easy_enums

Let your Rails app know about it

In the appropriate place in config/environment.rb add

config.gem "mschuerig-easy_enums", :lib => 'easy_enums'

2 Responses to “Simplistic Enumerations for ActiveRecord”

  1. on 28 May 2009 at 11:40Christoph Petschnig

    For exact the same problem, I find ConstantRecord very helpful. It is very lightweight and can be easily exchanged with ActiveRecord in both directions: http://github.com/ChristophPetschnig/constantrecord

  2. on 28 May 2009 at 12:05michael

    That’s interesting. How well does it work in more complicated settings, say as a condition in a query with several joins?

    I’ve written easy_enums primarily because I’d run into problems with another plugin that tried to avoid database tables for enumerations. Yours may work perfectly, I don’t know, but I’m wary nonetheless.

    Browsing around on Github, I just noticed enumerate_by. I’ll have a closer look at it and possibly deprecate my own stuff in favor of it.

Leave a Reply

Fork me on GitHub