Ruby Stuff

Adventures in Refactoring

Working on a legacy codebase will usually turn up some interesting nuggets. When entry into said project is prefaced with, “We know it’s bad, this was our first Rails app.”, you should brace yourself.

The fact is that there is a lot of bad code out there.  An awful lot of awful.  What approach should one take when trying to make it a little better?  I don’t have the silver bullet there, but I have been learning.  An approach I’ve found helpful on my current project is Focus/Test/Divide and Conquer.


In a perfect world, with unlimited funds from clients wanting you to give them a wonderfully built app, you can just start over from scratch.  As you already know, that is not the reality.  Your job, as an employee or contractor, is to get in there and make it work.  The key to doing this is realizing what is serviceable and what needs an immediate rewrite.  Rails has a built in way of making this easy with notes

  • #TODO: A task for the future
  • #FIXME: Note something that does not work and needs fixing
  • #OPTIMIZE: Refactor something that works, but is not well written

Boom!  Your app is your moleskine. Litter these throughout the project and access them whenever you want with a simple “rake notes.” If you are given a task to clean up database queries and, in the process, notice some other unsightly bits in an unrelated method, just note it and save it for later.


Now for the task at hand.  You might come across something like this:

wat. chop!  chop! chop! CHOP!!!!!!  Dear old Sweet Charlotte.

Anyway, looking at this code, it’s obviously got some issues beyond not following conventions.  As you would expect from looking at it, there were also no tests.

Step 1: Add rspec and factory_girl

Step 2: Add factories.

Step 3: Write a test.

After writing some factories for our models, we will put a test in to make sure we don’t break anything.

Perfect!  Now we can refactor.

Divide and Conquer

When code isn’t written well, it usually has bad organization, too.  A good step to take is putting the bad code in groups and in order.  Then look at each block and see what you can do to fix it.  The next series of code will show that process (the chops! are just… chopped).

The tests pass.  Let’s make it better.

So, we have our refactor.  A lot of times (especially for something as small as this), you might just do all of the dividing in your head.  That’s just fine, of course.  Just remember to ALWAYS CONQUER IN APP.