May 06

Using concerned_with and autotest for Rails models

Cashboard is growing to be a huge software project, over 11k lines of code, written in Rails.

Some of the models have gotten extremely fat using Jamis Buck's advice about "skinny controllers, fat models". One obese file in particular was causing me a ton of stress due to it's massive content, even though I comment liberally and tend to break up sections in the code with large ASCII dividers.

To compound the stress, my unit tests were also getting extremely bloated and hard to read. I couldn't tell if I'd tested a particular behavior at a glance. Things were becoming extremely hard to manage on both fronts.

I ended up searching out ways to break chunks of logic into separate files and finally settled on using the concerned_with trick for ActiveRecord.

Autotest problems

I'm a firm believer in using autotest while developing. There's no way I could manage a huge project like Cashboard myself without it. I've come to rely on it.

The concerned_with trick is great to break up logic into multiple files for one model, but I ran into some issues with the trick and autotest.

All of my tests for a model were still crammed into one huge file and the unit test didn't even run when I saved one of my new "concern" files.


Through some trial and error, I stumbled across a wonderful way to structure all of my files and hooked up autotest to recognize them all properly. Hopefully it helps someone else out there fighting with the same issues.

Right now I've got my project structured like so.

= app/models/  
  * account.rb
  * account/
    * billing.rb
    * validation.rb
    * ...

= test/units
  * account_test.rb
  * account/
    * billing_test.rb
    * validation_test.rb

Using this layout, I'd expect the billing_test.rb file to get run by autotest if I saved the billing.rb file. This is quite easily accomplished by adding a .autotest file to the root directory of your Rails project - as described in this article.

The contents of my .autotest file automatically map my concerned_with files to my custom unit tests for model behavior.

Written by Seth Banks

Seth spends most of his days leading the design team at Green Bits and improving Cashboard. Occasionally he finds time to write about music, design, startups, and technology.

Tagged: tdd, agile, rails