Ruby is the Force. Rails is the Dark Side.

A while back I wrote about “Uncle Bob” Martin’s The Lost Years of Architecture. As always it’s one thing to hear it and another to try and put it into practice, and I didn’t immediately have any architecture to think about. I’ve also been thinking about Corey Haines Fast Rails Test (“spec no rails”), which also has design implications.

Corey makes tests fast by not loading Rails. Uncle Bob says “A Ruby team fails if Rails is the first thing they do.” So, I’ve been trying to take pieces out of a Rails app and isolate them. I started by getting them to run in spec_no_rails, which I called spec_clean. For the first two pieces, I was making pure data queries to external services, so they didn’t depend on Rails in any meaningful way. I further extracted them to independent gems with their own tests. The result is that, so far, my spec_clean is empty – it makes me wonder if anything that can work in spec_no_rails should really be a gem.

The third piece does depend on Rails however – it has an ActiveRecord model, controller, and views. There are a couple of ways to separate parts of an app – the main ones being engines, and assembling multiple Rails apps as Rack apps. Engine don’t seem like quite the right answer – it’s designed for common functionality, while my goal is to isolate something that might eventually be it’s own service. Multiple Rails apps seems really heavy-weight, and maximally disruptive. In short, it’s proving difficult to disentangle the pieces.

“Once you start down the dark path, forever will it dominate your destiny, consume you it will…” – Yoda

Rich Hickey would say it’s Complected. Rich certainly picked on ORM and OOP. Uncle Bob (who responded to Rich) had the “The Lost Years of Architecture”: the internet craze, which includes web frameworks such as Rails. Part of my struggle is that I don’t know Rails well enough to know how to modify it, or even when not to use it. This is where Rails is like the dark side: it offers easy power, without requiring any of the upfront effort needed to understand what is actually going on.

“Grave danger you are in. Impatient you are.” – Yoda

To a certain extent, this is the same problem as with every framework – you are trading a great pile of already written and hopefully battle-tested code for no understanding of what you are actually doing. At some level every framework is the set of tools built up by someone to solve their own problems. It works great for that person because he built everything; he put in the work to understand all the pieces so he knows how they all fit together.

The 15-minute blog is a lie. (And Rails doesn’t even work that way anymore.) It won’t let you build anything besides 15-minute blogs. You have to do real work to understand the tools. And if you do understand the tools? Be careful playing with the dark side. If you shouldn’t call yourself a programmer, calling yourself a Rails programmer means your destiny has been dominated.

Posted Tuesday, November 1st, 2011 under Essay.

2 comments

  1. Yo(da), Mr. Justin.

    Been there, done that, and yup, yup, yup.
    For most things, the inscrutability of Rails should be considered a feature.
    We use tools to make our work go faster, better, easier.
    A tool that works well is a blessing.

    In the bad old days, I worked with Zope, a platform for which “the code is the documentation” was all too (sadly) true. It seemed nearly impossible to use the tool without having to go over all the little bits and pieces that made it up. Worst of all, the tool’s developers seemed to think that’s the way it ought to be.

    Rails developers at least have the decency to discourage going under the hood. That implies an understanding that people want to build applications with Rails, not re-engineer Rails itself. It also implies (one hopes) an obligation to make the framework usable in that manner.

    The rub — as you seem to have discovered — is that life happens. What do you do when the magic ceases to be wondrous and merely becomes a load?

    Keep us posted.

  2. It appears that multiple-Rails in a Rack isn’t actually an option. “ActionController::Dispatcher.new” doesn’t specify which application to run. On top of things like “Rails.root” etc. Global state for the loss.