Archive for February, 2007

REST, Rails, Skinny Controllers and Resources

Tuesday, February 27th, 2007

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.

Links for 2007/02/23

Friday, February 23rd, 2007

Simon Pegg on the difference between America and Britain.

Kathy Sierra gets all gushy.

Joel Spolsky spouts off about customer service and then Seth Godin tells us what we should really be doing.

And lastly, Andrew Hinton on using comics for your specification documents.

Overwhelmed

Friday, February 23rd, 2007

(self indulgent rubbish removed)

Keeping your head …

Monday, February 19th, 2007

A few techniques that I use to keep my head together at work:

  • Keep a log.
    • Every week I start a new text document and list my tasks for the week. Then, each day, I write down what I have been doing (with times).
    • I started doing this to help me fill out my timesheets but it actually turns out to be much more important than that.
    • Firstly, I get a vague measure of my achievements against my goals (or more importantly, how my goals by the end of the week have diverged from those at the start of the week).
    • Secondly, coupled with Spotlight (or Google Desktop or Vista’s equivalent), it can save your neck. We had a disgruntled customer – a quick search through my text files let me quickly build a log of every interaction I had with that customer. Armed with a dossier of facts they quickly called off the lawyers (although they remained disgruntled).
  • Use a To-Do list.
    • Every time anyone asks you to do something, write it down as a to-do item.
    • Give it a due date, a priority and a category. The priority and the category are up to you – it’s the due date that really matters. And if you don’t have a definite due date, make one up – give yourself a week, or a month, or whatever. But make sure you assign a date when you need to look at it again.
    • If that due date arrives and you are not in a position to complete, then move it back a couple of days. Write a note against the to-do item, explaining why you have moved it back.
    • If you are waiting on someone else then edit your to-do item: from ‘Do this’ to ‘F – Dave: Do this’ (F being for follow-up). Write a note against the to-do item, explaining what you expect of Dave and reschedule the due date. Then when the due date occurs, ask Dave if he has done what you ask of him. Reassign the task to yourself (‘F – Dave: Do this’ to ‘Do this’) or assign it to someone else. Or just leave it assigned to Dave. Reschedule the date. Write a note.
    • Repeat.
    • More often than not you are just pushing tasks into the future, as you are not in a position to complete. If possible, record a start date for your task as well, so you can measure how long it has been active (possible in Outlook but not in iCal).
  • Do not rely on e-mail as your communication tool
    • E-mail is great – mainly because it is simple and understandable and most of the people you deal with already use it.
    • E-mail is poor – it is not interactive and it has a fixed set of recipients.
    • The latter is a real problem – all too often an e-mail is sent to a massive list of recipients, to make sure that no-one is left out (cover your arse). This just means that a load of people are spammed on topics that don’t concern them.
    • All too often the people who need to be on a mail aren’t. So you add them into the ‘conversation’ later and forward copies of the previous correspondence.
    • E-mails are copies. You attach a Word document, pass it around and each person involved makes a couple of edits. Yet when Dave makes his edits, he uses a different version to the one that Claire made her edits on – so now there are two different versions doing the rounds.
    • Use a centralised repository for your discussions and files. We use Basecamp, but phpBB would do.
    • Have in-depth conversations over IM – use Group Chats and save the transcripts. We use Campfire but MSN (or Windows Live or whatever they call it) would do.

No guarantees but these tips have transformed me from living in a shambolic haze into someone regarded as organised. Which of course I’m not, but sometimes, it’s the perception that counts!

More on IIS and Rails

Monday, February 19th, 2007

Sorry folks – I’ve not been working with IIS recently.

But luckily, others have not been standing still. As well as Microsoft themselves looking at adding FastCGI support to IIS, the number of deployment options you have seem to be growing.

UPDATE: plus this one from Druid (in the comments but reprinted for clarity).

If search engines were girls …

Saturday, February 17th, 2007

Just discovered this gem:

Google is the bombshell who everyone drools over. She knows this and lords it over everyone. You’ve really got to work to get Google’s trust. She also has a weird fascination with blogging. Yahoo is wild and erratic. MSN is the world’s cheapest date, who will practically faint if you show any interest in her at all

Fake Steve on Linux …

Sunday, February 11th, 2007

no more letters from you guys trying to tell me that Linux is “better” than OS X. I’ve been making computers since before most of you were born, and I can tell you, categorically, that you know not whereof you speak

Excursion on the Subversion

Saturday, February 3rd, 2007

Have you ever used Microsoft Structured Storage? It is a COM API that allows access to ‘files and folders’ within a single file-system entity. For example, Word documents were structured storage – so all those embedded images and version history are stored as separate, accessible streams within a .DOC file. The API is actually quite easy once you get your head round it, but, like many COM APIs, it feels extremely complicated to use.

Apple (or more correctly NeXT) got around the same problem in a totally different way – using ‘bundles’. These are basically folders, not files. However, the (FTF)Finder treats them as a single file. Double click an RTFD file and it opens in TextEdit as if it were a normal document. Right-click and select ‘show package contents’ and you see that it is actually a set of folders, with your text, embedded images and so on. And because bundles basically use standard file system semantics, there is no complex API to learn.

However, structure storage works nicely with version control – just treat it as a binary file. Bundles almost work nicely with version control. svn add document.lineform treats your Lineform file as a folder and then adds its contents in the same way as any other folder.

I quite happily added a load of documents into subversion the other day and then made the mistake of moving them in the Finder. I successfully removed the old location from the repository. But whenever I tried to add the “new” copy I would get 'document.lineform is already under version control'. Yet a status command showed a question mark – meaning that the file needed adding.

It took me a while to figure it out, but eventually I got there. When you use subversion it creates a hidden .svn folder inside every folder. This creates all the status files – details of modifications, the original version and so on. And as bundles are treated by subversion as folders, they get these invisible folders as well. So when I moved my ‘file’ it copied these hidden folders as well. Hence subversion thought my file had already been added – it had subversion’s fingerprints all over it.

The solution? A quick rm -R -f document.lineform/.svn wipes out the hidden folder and we are back to normal.