Counterpoint: Rails and instance variables

A great thing about writing is that it focuses and sharpens one’s thoughts. The great thing about writing in public is that your thoughts, when passed through the brains of others, sometimes yield even better thoughts. The greatest thing about writing is when you hit publish feeling confident about your position and end up with your opinion flipped once the conversation is over.

So it went with A tale of two Rails view that a few hours after I’d published it, my mind was changed.

On the one hand, you can take a permissive stance on views and ivars. Dave Copeland nicely laid this idea out. If you are responsible about minimizing sharing ivars between actions and views, you have a chance. In this case, that means sharing one or two ivars, no more. Placing a little trust in your fellow developers lets you put off the day when you need to isolate state behind helper methods or other restrictive abstractions.

On the other hand, you can take a contractual stance on views and require all data passing between actions and view to do so through a specific object. Tony Pitale’s SimplestView does just this. It unifies views and partials into one name, “templates”, and then provides backing objects (somewhat confusingly called views). Actions create the backing objects and templates consume them. Nothing can leak through, no hunting down the origin of an ivar needed in this template but not yet defined in that one.

Somewhere in the middle are ideas about building a bridge between the action and the view. One could use responds_with as said bridge, but, for me, that felt like it played better with APIs than traditional views[1]. A possible middle ground is to use something like decent_exposure, or this interesting spin on it by Nathan Ladd. I like that Nathan’s approach is basically sugar over the pattern of encapsulating action state behind controller helper methods which are shared between views. I’ve been using the helper method approach so far, but it’s a little awkward to test and confusing for those used to sharing ivars.

If you’re sick of the baby and the bath water, you might find a more extreme approach interesting. Focused Controller and poniard do away with Rails conventions entirely. You still write controllers, but how you load data and model actions is entirely different. Personally, these are interesting sources of ideas. I’m not sure I’d jump on them for a production application.

Of all these approaches, I’m most intrigued by SimplestView. It seems like the Minimum Viable Departure from Rails conventions that could possibly solve the problem of sharing state and defining a contract on that state. That said, I’m likely to try Dave Copeland’s approach first. I like that it’s about talking with teammates, reviewing each other’s work, and making smart decisions. I’m finding that no amount of framework is as good at helping people write good code as review, feedback, and iteration.

  1. I know it works with normal views, but I didn’t like that it nudged me down the path of using conditionals. YMMV.  ↩