Close and Go BackBack to Viget

Maintaining Lookup Data in Your Rails Application

Patrick Reagan
Patrick Reagan, Development Director, April 22, 2008 0

Early last year, Dave Thomas gave a great talk on Metaprogramming in Ruby which he reprised last week at April's NovaRUG meeting. One of the quick examples he gave during the talk inspired me to work on an idea that began as a submission to Advanced Rails Recipes, turned into a Rails plugin, and which I just re-released as a gem. Basically, it allows you to cache the lookup data for your Rails models when your application loads.

Installation

Since we're hosting our code on RubyForge, a simple gem install will fetch the latest version:

sudo gem install constant_cache

Usage

Assuming that your application has a Status model with data that looks like this:

mysql> select * from statuses;
+----+----------+
| id | name     |
+----+----------+
|  1 | Pending  | 
|  2 | Active   | 
|  3 | Disabled | 
+----+----------+
3 rows in set (0.00 sec)

All that's needed is to include the gem in your model class and instruct it to cache its data:

require 'constant_cache'
class Status
  caches_constants
end

Status data is now available as constants on the class:

$ ./script/console 
Loading development environment (Rails 2.0.2)
>> Status.find(:all).map {|s| [s.id, s.name] }
=> [[1, "Pending"], [2, "Active"], [3, "Disabled"]]
>> Status::PENDING
=> #Status id: 1, name: "Pending"
>> Status::ACTIVE
=> #Status id: 2, name: "Active"

Since the constants point to ActiveRecord instances, the real value comes when you want to use them as part of an association:

user = User.create!(:username => 'preagan', :status => Status::PENDING)

The gem relies on a name column in your database, but can be configured to use something else as needed:

class Status
  caches_constants :key => :slug
end

Other configuration options are available, see the README file for more information.

Future Additions

Right now, the gem only handles caching data that exists in the database when the application is loaded, it isn't able to handle cases when the data changes (e.g. a record is deleted, or a name is changed). I plan to handle these cases in a future release. Feedback and patches are always welcome

Trackback URL: http://www.viget.com/trackback/1057/

Comments for this entry were closed after 60 days.

A Development Community for Viget Labs and Beyond

Every team member here at Viget Labs strives to be an innovator. We members of the development team are no different - that's why we're constantly engaging in community discussions and exploring the unknown that is the next generation of open-source web applications.

Viget Is Hiring!

Viget has job openings for Ruby Developers, Interns, and Front-End Developers. Learn More »

Recent Comments

I think that polymorphic_url(@commentable, :anchor => “comment_#{@comment.id}") should work. You can also refactor the “comment_#{@comment.id}” to a separated method, like dom_id, which returns the dom identifier of the comment.