The blog of Rahoul Baruah from 3hv Ltd

What's going on?

My name is Rahoul Baruah (aka Baz) and I'm a software developer in Leeds (England).

This is a log of things I've discovered while writing software in Ruby on Rails. In other words, geek stuff.

However, I've decided to put this blog on ice - I would ask you to check out my business blog here (or subscribe here).

27 February, 2007

REST, Rails, Skinny Controllers and Resources

Some time ago I wrote about how I was struggling to understand how the new style RESTful controllers work. In particular, it struck me that everything became a noun, when verbs were equally important.

After a few months of actually using RESTful Rails, I'm still struggling. The new-style controllers are significantly simpler (in particular I love nesting resources). Skinny controllers are a good thing.

But what if you need to create the same model from multiple places? For example, you may have a list of customers - so you can create one from there. But what if you need to create one "on-the-fly" whilst building an invoice?

In the "olden" days, I would have had an InvoiceCreationController that handled all the details of creating an invoice, including the new customer creation. As you can imagine, these could get pretty big and complex.

Should you reuse the original CustomersController? That means your controller needs to be told who is calling it, so it can render the correct response (in the "list" case you would want to return to the list of customers, in the "invoice-creation" case you would want to return to your partially created invoice).

So, who better to ask than Mr Buck himself? I mailed the Rails Way asking this very question and got this response back:


The "1-1 between controllers and models" is definitely not the case, and I tried to debunk that misconception somewhat in Part 1 of the SignOut refactoring. There is this idea in the community that resource == model, and that is not true. A resource _can_ be a model, but it can also represent an aggregation of models, or a slice of a single model. It can even represent something that isn't a model at all. A resource is something like "permissions", "sessions", "people", "logos", "files", "colors", etc. Basically, any noun you can extract from your domain can be a resource (though you probably don't want every noun in your domain to be a separate resource).

This sort of fits with an idea I had ages ago, about an object's aspects (this was pre-AOP) - that was also sort of hit upon by Allen Holub with his visual-proxy architecture. In other words, controllers are part of your user-interface, just as much as views are. They do not represent models. In fact, your user interface never represents models. Instead it represents things that matter to the user. That may map to a model. It may map to a collection of models. It may map to three attributes from one model and two from a related one.

So I guess for my example I want three controllers (keeping them nice and skinny) - one for creating your invoice, one for creating your customer (in the context of creating an invoice) and one for managing customers in general.

No comments:

eXTReMe Tracker