Give attribute_mapper a try

(For the impatient: skip directly to the `attribute_mapper` gem.)

In the past couple months, I’ve worked on two different projects that needed something like an enumeration, but in their data model. Given the ActiveRecord hammer, they opted to represent the enumeration as a has-many relationship and use a separate table to represent the actual enumeration values.

To a man with an ORM, everything looks like a model

So, their code ended up looking something like this:

class Post < ActiveRecord::Base

  belongs_to :status

end

class Status < ActiveRecord::Base

  has_many :tickets

end

From there, the statuses table is populated either from a migration or by seeding the data. Either way, they end up with something like this:

# Supposing statuses has a name column
Status.create(:name => 'draft')
Status.create(:name => 'reviewed')
Status.create(:name => 'published')

With that in place, they can fiddle with posts as such:

post.status = Status.find_by_name('draft')
post.status.name # => 'draft'

It gets the job done, sure. But, it adds a join to a lot of queries and abuses ActiveRecord. Luckily…

I happen to know of a better way

If what you really need is an enumeration, there’s no reason to throw in another table. You can just store the enumeration values as integers in a database column and then map those back to human-friendly labels in your code.

Before I started at FiveRuns, Marcel Molina and Bruce Williams wrote a plugin that does just this. I extracted it and here we are. It’s called attribute_mapper, and it goes a little something like this:

class Post  {
    :draft => 1,
    :reviewed => 2,
    :published => 3
  }
end

See, no extra table, no need to populate the table, and no extra model. Now, fiddling with posts goes like this:

post.status = :draft
post.status # => :draft
post.read_attribute(:status) # => 1

Further, we can poke the enumeration directly like so:

Post.statuses # => { :draft => 1, :reviewed => 2, :published => 3 }
Post.statuses.keys # => [:draft, :reviewed, :published]

Pretty handy, friend.

Hey, that looks familiar

If you’ve read Advanced Rails Recipes, you may find this eerily familiar. In fact, recipe #61, “Look Up Constant Data Efficiently” tackles a similar problem. And in fact, I’m migrating a project away from that approach. Well, partially. I’m leaving two models in place where the “constant” model, Status in this case, has actual code on it; that sorta makes sense, though I’m hoping to find a better way.

But, if you don’t need real behavior on your constants, attribute_mapper
is ready to make your domain model slightly simpler.

Just For Fun

This year was my fourth RubyConf. I’ve always come away from RubyConf energized and inspired. But, I’ve yet to follow through on that in a way I found satisfying. I have a feeling I’m not alone in that camp.

This was the first year I’ve given a presentation at RubyConf. At first, I had intended to use this watershed-for-me opportunity to ask whether Ruby was still fun. There’s been a number of “drama moments” since my first RubyConf; I thought it might be worth getting back to my early days of coding with Ruby, when I was exploring and having a great time turning my brain inside out.

As I started researching, it turned out that there are a lot of people having fun with Ruby. Some are doing things like writing games, making music or just tinkering with languages. Others are doing things that only some of us consider fun. Things like hacking on serious virtual machines, garbage collection, and asynchronous IO frameworks.

So, back to my talk. I saw my failure to harness the motivation what I’d seen at previous years at RubyConf as an opportunity to figure out ways to line up some tactics to make sure that after the conference, I was able to create awesome things, contribute them back to the community, and enjoy every minute of it.

Thus, I came up with a sort of “hierarchy of open source developer needs”. At the bottom is enjoyment; there’s little sense doing open source work if you’re not having fun. Once you’re having fun, you probably want to figure out how to find more time for making codes. Once you’re making more codes, you want to figure out how to get people interested in using your stuff. I’ve taken these three needs and identified several tactics that help me when I find myself in a rut or unable to produce. Call them patterns, practices, whatever; for me, they’re just tricks I resort to when the code isn’t flowing like I want to.

The talk I ended up with is equal parts highlighting people in the Ruby community that are having fun and highlight ways to enjoy making things and contributing it back to whatever community you happen to be part of. I hope that I avoided sounding too much like a productivity guru and kept it interesting for the super-technical RubyConf crowd.

If all of this sounds interesting you, grab the slides (which are slightly truncated, no thanks to Keynote) or watch the recording from the conference itself.


I wrote the proposal for this talk right after Why disappeared himself. His way of approaching code is what inspired me to write a talk about getting back to coding for fun. “Just for Fun” starts with a tribute to Why the Lucky Stiff. The sense of fun and playfulness that Why had is important to the Ruby community. I’ve tried to highlight some of his most interesting playful pieces. And in the end, I can’t say “thanks” enough. Why has inspired me a lot and I’m glad I got to meet him, experience him and learn through his works.

Even if you don’t take a look at my presentation, I strongly urge you to give a look at some of Why’s works and let them inspire you. My favorites are Potion and Camping.


Some other things I mentioned in my talk as interesting or fun:

The Kindle's sweet spot

Given all the hubbub about Kindles, Nooks and their utility, I thought this bears repeating to a wider audience:

The Kindle is great for books that are just a bag of words, but falls short for anything with important visuals.

I’ve really enjoyed reading on my Kindle over the past year. You can’t beat it for dragging a bunch of books with you on vacation or for reading by the poolside. That said, I don’t use it to read anything technical with diagrams or source code listings. I certainly wouldn’t use it to read anything like Tufte, which is exactly why his books aren’t available on the Kindle. Where the Kindle shines is with pop-science books like Freakonomics and Star Wars novels1.

If you love books and reading, the Kindle is a nice addition to your bibliophilic habit, but it’s no replacement for a well-chosen and varied library.

1 Did I say that out loud? Crap.

Testing declarative code

I’m a little conflicted about how and if one should write test code for declarative code. Let’s say I’m writing a MongoMapper document class. It might look something like this:

class Issue

  include MongoMapper::Document

  key :title, String
  key :body, String
  key :created_at, DateTime

end

Those key calls. Should I write a test for them? In the past, I’ve said “yes” on the principle that I was test driving the code and I needed something to fail in order to add code. Further, the growing ML-style-typing geek within me likes that writing tests for this is somewhat like constructing my open wacky type system via the test suite.

A Shoulda-flavored test might look something like this:

class IssueTest < Test::Unit::TestCase

  context 'An issue' do

    should_have_keys :title, :body, :created_at

  end

end

Ignoring the recursive rathole that I’ve now jumped into, I’m left with the question: what use is that should_have_keys? Will it help someone better understand Issue at some point in the future? Will it prevent me from naively breaking the software?

Perhaps this is the crux of the biscuit: by adding code to make certain those key calls are present, have I address the inherent complexity of my application or have I imposed complexity?

I’m going to experiment with swinging back towards leaving these sorts of declarations alone. The jury is still out.

Texas is its own dumb thing

Southern American English

OK, here’s the deal. Wikipedia has it all wrong.

  1. Texas is not part of the South. Texas is its own unique thing. Sure we have dumbasses, but they are our dumbasses, wholly distinct from your typical Southern dumbass.
  2. In Texas, the way you refer to “you all” is “ya’ll”; it’s a contraction of “ya all”.
  3. They neglected to mention the idiomatic pronunciation of words like “oil” (ah-wllllll) or “wash” (warsh).

Please take it under consideration: Wikipedia is edited by a lot of damn Oklahomans.

Curated awesome, the 1st

A bumpy subway wall, loving things for their Unix-y qualities, Kurt Vonnegut looking dapper, the final movement of Dvorak’s Ninth Symphony (originally his fifth), and a music video by Talib Kweli that makes me want to go get my hair cut. Oh, and I can’t leave out the connection between prototyping physical things and applications operating on large data, Ben Scoffield’s take on database taxonomy and a screed on reading one book per week.

(Editor’s note: I recently took to using Tumblr again. For a while, I’ve been curating interesting stuff here. But Tumblr has evolved into a really fantastic application for doing this. So, my policy going forward is to post my stuff here and curate other people’s awesome stuff over there. That said, I’ll probably do “best-of” posts, like this one, to keep you interested and informed.)

Chance Encounter

Another meme-ish “film” by yours truly. This time, the idea is you do something in five seconds, plus a two second intro and a one second outro. Here’s what I came up with:

This is an adaptation of possibly my favorite improvised joke. I deploy this joke when a conversation is interrupted by some disturbance or noisy distraction. Right before the conversation is going to continue, I say “…and that’s how I met the president and the pope on the same day.” Works pretty well.

Funny aside: I found out about this on the Vimeo site, thinking there was a competition this weekend. Turns out, it was last weekend. Figures.