Query actions in Rails controllers

Recently some of my controller actions have taken on a definite new shape. Particularly when the action is a read-only query of the app’s state. Such actions tend to make up the bulk of my apps, and they can be simple because they are unlikely to “fail” in any predictable way. Here’s an example from my wiki app:

This has a couple of significant plus points: First, no instance variables, so both the controller action and the view are more readable and easier to refactor. Second, no instance variables! So there’s a clear, documented, named interface between the controller and the view. And third, this is so transparently readable that I never bother to test it.

The wiki used in the above action is a repository, built in a memoizing helper method that most of the controllers use:

In this case the correct kind of repository is created for the current user, and all of the other code in this request sits on top of that. So the controller action, helped by the memoized repository builder, effectively constructs an entire hexagonal architecture for each request, and the domain logic is thus blissfully unaware of its context.

Here’s a slightly bigger example. This is for a page that shows a variety of informative graphs about the wiki; and because I may want to re-organise my admin pages in the future, each graph’s data is built independently of the others:

That’s the most complex query controller action I have, and I maintain that it’s so simple I don’t need to test it. Would you?

Hexagonal rails: Rake tasks are adapters

If I’m thinking about my Rails app in terms of a hexagonal architecture, I find it also pays to consider every rake task to be an Adapter. Thus:

Picture: @rosieemackenzie

The true picture is a little more complicated than that, but the principal ideas are there. The rake task acts as a mediator, allowing me to send messages to (ie. call methods on) my application’s objects.

In general, we want our Adapters to be as thin as possible (and no thinner). That’s because the Adapter code inherently depends on some framework, and that fact will usually make its tests difficult and/or slow. We still need those tests, but we want to have as few paths through the Adapter as possible, and thus fewer tests of the Adapter, so that the total test complexity and test run-time are minimized.

As an example, suppose I have a rake task that validates the posts and comments on my blog:

I want to maximize the unit tested percentage of the code executed during the task, so I move the code out of the rake task and into a new domain object. That new object “is” the task, and usually my rake tasks can then slim down to a single line of code.

Stripping all of the code out of the rake task and moving it into a domain object is analogous to the approach currently being explored by @mattwynne and @tooky in their Rails controller refactorings. In my own code I call these task objects “use case objects”. Currently I keep them in a UseCases namespace within app/models, although I’m open to exploring alternative conventions. One of the nice side-effects of this is that I sometimes discover synergies between the work done by rake tasks and that done by controllers. By pulling Use Case objects out of both kinds of adapter I’m creating a convention for some of the code that turns out to be cleaner, more (quickly) testable, and which names things better.

Please let me know if you try this — or indeed if you’re already doing it.

Hexagonal rails: Hiding the finders

This is a brief follow-up to the Hexagonal Rails sessions I did last week at the Scottish Ruby Conference with Matt and Steve. We tried to cram a 3-day course into 45 minutes, with inevitable consequences. So by way of an apology, here’s another brief foray into some of the same territory…

Today I’ve been exploring ways of improving the unit tests in one of my Rails apps. Let’s pretend it’s a blog app, and I have to add a feature to publish posts. I’ve pulled some code out of a controller to make a UseCase object:

(Here ui is a controller, and makes decisions about routing and rendering in response to the events sent by the use case object.)

I’m really sick and tired of looking at code like this. It seems that most of the classes in any Rails app know that finders return nil when they can’t find something, and so they all have to cope with that case. I want to get rid of that if, or at least hide it away in a single place so that it doesn’t contaminate the rest of the app. I want the test to be a bit simpler and more readable too. And I want the option to have richer finders, maybe coping with fuzzy edge cases and still finding the desired database record. In short, I want to wrap the finder in an Adapter.

So I experimented with a couple of alternatives to the above. First, a variant on Smalltalk’s ifTrue:ifFalse message argument style:

I don’t like this because it’s near impossible to isolate and test the interactions. For example, Blog.should_receive(:lookup_post).with( … what?

Another approach might be something like this:

Indeed Rails itself uses this style in its controllers, and so does the inherited_resources gem. But it suffers from the same testing problems as my previous attempt. So I finally settled on this:

This version uses an explicit listener object, which I can thus instantiate and test independently of the calling context. (In real code I might make it an inner class too.) And I’ve already found a couple more uses for the lookup_post method, removing dependencies and ifs along the way.

I find this approach highly readable and testable, nicely separating different responsibilities and allowing me to give them names. But that doesn’t mean I’ll stop exploring. Have you tried other approaches? How did they work out?


Luke points out that I forgot to include the option I actually use the most, the Self Shunt:

This is the same as the listener option above, but the UseCase object passes itself as the listener, thus saving a class and in my opinion) improving readability a little. Can’t think why I forgot it, cos it’s the best and neatest of them all. Anyroadup, thanks Luke!

Conditionals on the edge

As you know, I have a thing about conditional code. Most conditionals are duplicates, and the only “genuine” conditionals are at the system boundaries, where they test external state and input information. But I discovered recently that, even at the edges, not every conditional is necessary…

Here’s (a drastically simplified version of) some code I wrote a while back. (It’s from a Rails app, but the message in this post applies to any technology and any kind of system input.)

class Users::RegistrationsController < Devise::RegistrationsController
  def create
    user = create_new_user_account
    if params[:invitation_token]
      redirect_to Invitation.find(params[:invitation_token]).shared_content
      redirect_to new_user_session_path

This route handles incoming user registrations, and it has a conditional branch to cater for the case in which the new user was invited, via email, by an existing user. If the new user arrived by clicking a link in an email we do one set of things; whereas we do a different set of things if the user got here via the ‘Register now’ button on the home page. Perfectly reasonable, I thought. Sure, it’s conditional code; but it’s sitting on the system boundary and therefore it’s fine, yes? No.

This conditional check represents duplication. Somewhere else in my application already knew, at some time in the recent past, which route should be taken through this method when it was finally invoked. When the app sent that email invitation, it was in a sense delegating to the recipient the task of supplying user account details. The conditional branch that handles the invitation is a callback from across a technology boundary, and the inviting code already knew to expect it.

The duplication also has a nasty side-effect: high complexity. This method is an order of magnitude harder to understand and to test(-drive) because of the conditional construct. (And you’re reading a version from which I’ve elided all manner of error handling.) Oh, and by forcing two routes into the same method I also made it violate the Single Responsibility Principle.

Happily the duplication is really easy to remove. The code that sends the email invitation knows which path it wants the registration code to take, so I just need to create a new input route for “invitation acceptance” and change the email invitation to link to it. As a result I’ll have two controller methods, each with simpler logic than their predecessor:

class Users::RegistrationsController < Devise::RegistrationsController
  def create
    user = create_new_user_account
    redirect_to new_user_session_path


class InvitationAcceptancesController < Devise::RegistrationsController
  def create
    user = create_new_user_account
    redirect_to Invitation.find(params[:invitation_token]).shared_content

So I have now removed the duplication, and the controller code is simpler as a result. These controller methods are also much easier to test(-drive) than the earlier code. And as a final bonus, I can design the user interface to this route with more knowledge, maybe adding some details of the invitation so that the incoming potential user feels a little more at home. In short, now that each code path has its own method (and class) I can pay it more attention, and it will flourish as a result.

Now, having refactored this code, I take away a few points for the future:

  • Where appropriate and possible, model system outputs as delegations into a space that your code can’t reach or control; and model the resulting future input as a response.
  • Where a system input is due to the system having earlier delegated a responsibility across its boundary, make sure the return route is differentiated from all others.
  • Differentiated incoming routes have code that is easier to read and simpler to test.
  • When an input route has a single use, the user experience can be tailored and enriched.
  • Not every conditional at the system boundary tests external state.

in-place editing in Rails 2.0

During the holiday break this week I decided to fix up one of my old projects and get it working under Rails 2.0. Things went well until last night, when I tried adding Ajax-style in-place editing to one of the forms. It doesn’t quite work as advertised, and the relevant information is scattered over the web, so these notes bring everything together in one place. (After the event I found Yen-Ju Chen’s notes, but they’re hard to find when you don’t know what to Google.)

First, as of 2.0 the in-place editing helper methods have been removed out of Rails and into a new plugin called in_place_editing. Unfortunately it doesn’t work on a simple out-of-the-box app: if you try it you’ll see an InvalidAuthenticityToken error reported in the log whenever the browser attempts to set the form field to a new value.

It turns out that this is a known defect in the new plugin, and thankfully there’s a patch provided on the defect report. Apply the patch and in-place editing works!

After the episode was over, I was struck by the power of the open source community. At 9pm I was cursing the incomplete, haphazard and dispersed documentation for the tools I was using; and at 10pm I was marvelling at the worldwide group of volunteers who found the defect, published a fix, and provided all of the tools required to manage that whole process and allow me to upgrade my installation. I’m awestruck when I try to list the layer upon layer of software that made that little code change possible, and by the legions of volunteers whose efforts have driven the evolution of today’s tools. The future’s bright — the future’s open.

setting up eclipse for rails

I’m starting out on two new Rails projects this week, so I’ve been investing some time in getting Eclipse configured nicely. There are dozens of helpful websites containing helpful advice, and after much trial and error I found a couple of these that worked really well for me.

For setting up RDT (the Ruby Development Tools) I found Brian Hogan’s Setting up a Rails Development Environment on Windows Using Eclipse to be the most complete and accurate resource. However, it doesn’t cover RadRails. For that, I recommend Victor Kane’s RadRails Tutorials. Both of these sites provided complete and correct advice that worked straight out of the box.

But only after I had spent much of last week struggling with the Cygwin version of ruby. I’ve been an old Unix hand since before I could walk (I wrote some small parts of the System V kernel, would you believe). So when I work on a Windows box, one of my first actions has always been to install Cygwin and make it seem a little more like “home”. But not any more. It’s just too hard to get Cygwin, Ruby, gems, Eclipse, Rails, Apache, MySQL and Subversion all working together. Either the DLL versions are in conflict with each other, or something coredumps regularly, or something needs to be compiled with one in order to work with the other. At every turn I came up against stuff that was known not to work. So in the end I have reluctantly decided that I must be congruent, and not try to pretend that Windows is Unix. It was a painful decision, but so far it has paid off.

Now, to get on with some development…