August 2nd, 2008

I’ve been thinking lately.. controllers.. they’re just state machines. Sure, most controllers don’t have much state. They implement CRUD, which means the only state you need is the state of validness of your model. The control flow is directed by #valid?, with maybe a confirm message for #delete.

But shopping carts are not that simple, and probably shouldn’t be. You want to collect the user’s purchased items, their address, credit card, and then confirmation of it all. In that order. Making them create/read/update/delete an address, create/read/update/delete a credit card. Then having them add the address, credit card, and items to a Basket object. That’s just too many steps and anyone can tell that would be really silly as a user flow.

Could you reduce 95% of controller actions to just CRUD? Yes, you probably could. But that’s now how we think. Sometimes you need more than one step to produce a good user flow. Even with Ajax, you still sometimes want to reload the entire page, or allow older browsers to use the functionality easily.

No.. Controllers ought to be modeled after the user flow, not what’s easy (or hard) about the development process. The reason that web apps tend to be so simple is not because of some intuitive understanding of what the user wants.. And I’m sure that simple apps win over complicated ones any day. No. While I would rather write simple code, sometimes the domain model expects more. But we don’t have any off-the-shelf abstractions with which to go above the request/response cycle.

We need a plugin that can do this. We need an acts_as_state_machine for controllers. I’m probably not going to write it, since I’m neck-deep in other projects, but if I had the time, I would. It would need to be a macro of some sort, something to maintain session variables as they go in and out of scope. With maybe even possibly a state chart to show what the user flow looks like to clients and less tech-oriented types. That would definitely help to get a mental snapshot of where things might screw up.