Archive for the ‘Application Design’ Category

Wednesday, May 21st, 2008

Sometimes, it’s worth stating the basics for all to see:

  • Follow the Model-View-Controller paradigm.  In particular, your views house your user-interface, your models handle the application and your controllers mediate between the two.  Controllers do not contain rules, conditionals dealing with business conditions, queries looking for objects related to the one in question.  All those things belong in the models.  
  • Use ActiveRecord conventions at all times.  It may not be the most efficient thing in the world but for most of you out there, it doesn’t matter.  
  • Use ActiveRecord and migrations to define and manage your database.  All your business related stuff stays in one place - the models - including defining relations (associations), validations and rules.  In particular, ActiveRecord associations makes some tasks easy (very simple many to many relations) and gives you things (such as polymorphic associations) that you can’t safely define using straightforward SQL.  With judicious use of validations you can ensure that the data stays safe.  
  • Use RESTful designs in your controllers.  This means that your controller very rarely grows beyond seven actions (index, show, new, create, edit, show, destroy) - and RESTful routing ensures that GETs and POSTs go to the right places.  If you need to extend things then add a sub-controller.  For example, if you were transferring an employee to another, you could have a route: /employees/1 for the employee him/herself, /employees/1/transfers/new to let the user define which company the employee is moving to and /employees/1/transfers/create to actually do the transfer.  And if you’ve defined your model correctly, the implementation of /employees/1/transfers/create should be as simple as @employee.transfer_to(@company)
  • Write your tests (or specs) first.  One - this gives you a series of small wins, which is good for your self-esteem.  Two - it helps to clarify your thinking.  ”I need to write something that does X and Y, resulting in Z … oh hang on, do I really need Y?  What about U and V?”
  • Use mock objects when testing your controllers.  Why bother coming up with lots of test data when all you really need to say is “if I the model saves correctly then redirect to X, if it doesn’t save then show Y”.  In the “transferring employees” example above, you only need to test that the controller calls “transfer_to” on your model.  Of course, your model will have already tested that transfer_to does what is expected of it.  
  • If you find yourself repeating a bit of code, or writing something similar then STOP and refactor.  Add methods to the application controller, create a new controller descendant, stick it in a view helper, add a module to your models, write a partial (and if it needs parameters, write a helper that takes a set of parameters and does the call to render :partial for you)
  • Did I say write tests and specs first?
  • Oh, and if it starts getting complicated you’re almost definitely doing it wrong.  
Sunday, January 6th, 2008

Normally I wouldn’t talk about Ruby on Rails on this blog. That geek talk is found on the tech blog instead.

Wondering?But, despite being about Rails, this isn’t a tech post. It’s about a problem that you will face when trying to hire a Rails developer.

Rails has a number of advantages.

  • It is a framework that gives you a massive head-start when building database-driven web sites.
  • It is designed to make programming fun. Meaning that the developers shoot through the work with a smile on their faces (rather than scowling and procrastinating).
  • It is opinionated and works much better if you follow the “Rails way” - that is a set of patterns and styles that are generally accepted as best practice within software development.

It is the last point that causes the problems.

You see, software development is still a relatively young industry. It is a craft, not a science. There are some who regard it as an art, maybe even a dark art. A lot of software development goes over budget simply because the staff are discovering new ways to do things - and you can’t budget for the unexpected.

But things are changing. Rails is proof of that. There is forty years of case history on the best way to solve certain kinds of problem. Most “business” applications are all about storing, retrieving and presenting information as easily as possible. The tricky, unknown, bit comes when you want to manipulate that data - but the majority usage is simple storage, retrieval and presentation.

And that is why Rails is great - it is designed to standardise storage, retrieval and presentation. It has rules that you should follow - and if you do your code will be elegant, reliable and on-budget.

The difficulty is knowing about those rules and why you should follow them. And herein lies the problem. When I discovered Rails (in the middle of 2005) it was a breath of fresh air. An environment that was about following the rules that we all knew we should, but never did. That actually made it easy to follow software-engineering-best-practice. That assumed you knew what you wanted to do and helped you do it. But the key was that I already knew the rules and why they were important, which in turn came because I had years of study and experience within my field.

If you hire a Rails developer tomorrow, how do you know that they understand those rules? Anyone can learn to program in Ruby - it’s a pretty easy language to learn. Anyone can knock together a few sites in Rails - it’s designed to get you started quickly. But do they know that your application logic belongs in models and not controllers? Do they know why your application logic belongs in models and not controllers? Don’t worry - you don’t need to know about models and controllers - that’s your geek’s job. However, if they can’t give a decent answer to either of those questions, they’re not a proper Rails developer. And you probably don’t know which questions to ask, let alone how to evaluate their answers.

Well, I have been using Rails, on commercial projects, for years now. The ideas behind it are second nature to me. I have seen how inexperienced developers can make a mess of a decent project yet still charge massive fees. I have seen how a project can take a wrong turn, when a simple explanation can change things for the better. How asking the right questions and looking in the right places can point you in the right direction.

So, if you are unsure of how your project is progressing, if you need to evaluate what your developers have produced, if your team is looking for guidance and if you want a series of specific recommendations for improvement then (although I am still finalising the exact details of the service) feel free to contact me today for more information on how 3hv can help. And, if you’re not quite ready, why not subscribe to make sure you stay up to date.

Update: You can read more about how this service works on the tech blog.
Photo: “Wondering” by bigevil600.

Tuesday, December 11th, 2007

Blackfriars Marketing commenting on Bill Gates’ claim that Enterprise Software gets little respect (via the Wall Street Journal).

As someone who has worked on ‘business’ and ‘enterprise’ software for most of my career (the difference being one of scale as far as I can see) I wholeheartedly agree. I got sick of being told that the user-interface was ‘good enough’. Half a second of frustration quickly adds up if you are sat in front of an application for eight or more hours a day(*).

especially when we confront real systems at work that increase workloads, enforce meaningless restrictions that don’t help customers, and sport user interfaces that feel Kafka-esque in their user hostility. It’s not surprising that enterprise software gets no respect; it is surprising that there aren’t more cases of employees throwing their computers out windows in frustration.

(*) Incidentally, that always used to be my response when people said that Windows had achieved parity with the Mac user experience. Give two experienced users a tight deadline, one on a Mac, the other on Windows, and see who swears the most. Frustration => Unhappiness => Staff Turnover (for the buyer) and No Repeat Sales (for the vendor)

Friday, November 9th, 2007

rake db:fixtures:load is probably one of the most useful commands I have used recently.

You see, I was meeting some people about some potential work. They wanted to see an example - preferably related to payment systems. I had some code but unfortunately, the service that is part of had been switched off (a number of reasons, none of which connected to my supreme stylings). I had a copy of said code on my machine, but no database and I had no time to prepare.


So how could I demo it? Easy peasy.

cd ~/Source/my_apprake db:migraterake db:fixtures:loadruby script/server

And then start Camino.

Because the application had been developed test-first I knew that there was a decent set of data within those fixtures. Data designed to show all the edge cases, all the complexities of the application. From users and logins through to payment records and customers.

It is fair to say that when writing your applications, test-first, the fixtures are the hardest thing. It can take ages and it is detailed, painstaking work. Especially if you are trying to build a narrative (:dave logs in, selects a :cucumber, goes to the :checkout, pays with his :expired_credit_card which is rejected).

But the benefit is there. Building a narrative helps you when you come back to the code in six months time. Defining a wide-range of test fixtures helps you when you make changes and need to ensure that it won’t break a feature over there. And it helps you demo your code in front of a prospective client when faced with the unexpected.

Data Highway by KLatham.

Thursday, October 25th, 2007

You know how it is - there are some things that you are just not comfortable without. My phone in my back pocket, my wallet in my front pocket, the key in the front door when I go to bed (just in case there’s a fire and we have to make a hasty exit), the dog under my feet (tripping me up), one of my large collection of jackets (current favourite: leather biker jacket).

And so it is with Rails projects. Before I do anything I do the following:

  • Load the Exception Notification plug-in and configure it with my email address
  • Load the form_test_helper plug-in so I can confidently test my forms
  • Load the ARTS plug-in so I can confidently test my AJAX user interfaces
  • Load Markaby so my views are beautifully coded and semantically correct
  • Create the Rails session store within the database (rake db:sessions:create)

Of these, the one I really can’t do without is Markaby (although ARTS comes a close second). I don’t know what it is (apart from Why the Lucky Stiff is genius). I can’t stand looking at rhtml files any more - too many angle brackets for a start. Instead, my mabs are things of beauty - and as I write the code to produce the views, I find that they are more semantically correct as well. For example:

div.row do  label “Email Address: “  text_field :person, :email_address  p.explanation “Please supply a valid email address so that we can send you a confirmation email”end

As I’m writing the Markaby code, class names like “explanation” seem to fit naturally - the code reads better, the HTML is semantic and the CSS is simple.

What more could you want?

Wednesday, October 3rd, 2007


I’m just thinking out loud here - based on stuff I’ve done well in the past. But this is no rigorous scientific method - just a set of notes for me to refer back to.

* Write a couple of paragraphs describing the application. Note down keywords (especially important nouns and verbs) and maybe a “what, who, why and how” type analysis (when and where may or may not be applicable, depending upon the application).
* Show this to other people and get their feedback.
* Sketch out the UI. On paper, with a 6B pencil and an eraser, or on a whiteboard, with a camera. Do a flowchart for each of your major tasks (look at the verbs from before) and then a quick sketch of the pages involved. As you sketch out the pages you will probably find that you need to change the flowcharts. Think long and hard about it and then change if you must.
* Show this to other people and get their feedback.
* Create a new project and add it into subversion.
* Take your flowcharts and decide which controllers will be involved in each task. [I’m not sure about this point - but I reckon you probably don’t want a single controller to be involved in more than one task - however each task will probably require many controllers].
* Generate the controllers and then use them to create static HTML/CSS mockups of your UI. The only “active” portion of these mockups should be links navigating through the task. As you do the mockups you will probably think of new functionality - add these to your flowchart immediately - if it becomes apparent when you have actual pages in front of you it’s probably valid (as opposed to the “up in the air” additions above).
* Get your mockups to respond to a parameter: mockup_style; if this is blank then show the page, if this is “empty” then show the “blank slate” page, if this is “error” then show the “error” page. In other words, think about how it looks in those three important states up-front.
* Show these mockups to people and get their feedback.
* Write functional tests for your controllers. Deal with things like showing the blank slate page when there is no data to display (I like to use assert_select to search for a div called “whatever_blank_slate”).
* Dealing with each controller in turn, get the functional tests to pass. In order to do this, you will probably have to create models. As you create the model add unit tests and test fixtures - and then use these to make the functional tests actually work with real data in a real database.
* Do the bare minimum to the models, fixtures and unit tests to get the functional tests to pass. Even if you know the next controller will need a new method adding to the model, don’t add it in early. You never know - your boss may change his mind and decide that that function is not needed (or more likely, can wait till version 1.1) - in which case, why make things complicated before it is needed?
* Whenever you find yourself writing code that is similar to code elsewhere within the project stop and refactor it into a helper, a method on the controller, a base (inheritance) model class or a mixin module. Don’t Repeat Yourself.
* Related to the above, put business functionality into the models (unit tested) - for example if your view needs to show the last four invoices but one, add a method to your customer class called “last_four_invoices_but_one”. Don’t get your controller to grab all the invoices and slice the array itself.
* Once all your functional test passes, run the app in at least two (preferably three) browsers. In theory, if your functional tests are any good, you should see pretty much a working task. Any bugs you find should be reproduced in the tests, if at all possible, and then fixed.
* Show this to people and get their feedback.
* Refactor your controller and models to tidy them up. Remember you have very high test coverage so you should not break anything without being alerted to the problem.
* Move on to the next functional test.
* When they are all done - you should have a working application!
* When the inevitable changes requests come in, you should have full coverage of unit and functional tests, making change management easier than it would be without those tests.

As I say this is thinking out loud - I’ve never done all of these at the same time - but I’m certainly planning on following this process on one of my own projects in the near future.

Gears by csotelo.

Tuesday, October 2nd, 2007


I remember years ago, when Object-Orientated Programming became fashionable, every single text on it (at least those that I could be bothered to read) repeated the mantra “OO is about inheritance”. Of course, that’s rubbish, but when you’ve been dealing with structs in C or Cobol it’s probably an easy way of thinking of things - objects are these data structures with these extra bits.

Nowadays, I rarely use much inheritance, beyond extending what my framework gives me. And I find myself using it much more in statically-typed (compile-time type checked) languages. I think splitting my functionality into a web of tiny objects gives me much more flexibility (as opposed to ending up with a couple of huge objects with layers of functionality added through generations of inheritance). Think of a chain of people - you ask a question of A, who in turn asks her friend B, who in turn asks his boss C, who in turn asks his wife D. In a different situation you may ask the question of B who gets the answer off A. Each of A, B, C and D is small and simple with a tiny public interface. Compare that to asking every question of an ABCD amalgamation - large and unwieldy with a large public interface.

Of course, Ruby does allow inheritance. It’s not always needed for reuse as you have mixins, but there are times when it is useful. And Rails lets you use inheritance in your models - it’s not always needed as, for joining disparate classes together you can use polymorphic associations, but there are times when it is useful.

So now I’ve tried to warn you off, how do you do it?

Imagine an address book application. You have basic AddressBookEntries which fall into two categories - People and Companies. This is an excellent candidate for inheritance as there is a fair amount of stuff shared between People and Companies (name, address, telephone number) but also some different stuff (People belong to Companies, Companies have a list of People and a VAT (tax) number).

To start with you create a model - AddressBookEntry.

Your migration may look like:

create_table :address_book_entries do | t |  # system fields  t.column :created_on, :datetime  t.column :updated_on, :datetime  t.column :lock_version, :integer, :default => 0  t.column :type, :string  # common fields  t.column :name, :string  t.column :address, :text  t.column :telephone, :string  # person specific fields  t.column :company_id, :integer  # company specific fields  t.column :vat_number, :stringend

Note that we have split the fields into different sections - system fields, common fields, person fields and company fields. Not strictly necessary but a nice to have.

Our model looks like this:

class AddressBookEntry < ActiveRecord::Base

end

But where are our people and companies?

Two new model files - person.rb and company.rb are needed.

# person.rbclass Person < AddressBookEntry  belongs_to :companyend# company.rbclass Company < AddressBookEntry  has_many :peopleend

There you go. All done (apart from the unit tests).

So how do you use this?

Simple - create a company and a person.

tiny_co = Company.create :name => ‘Tiny Co’, :address => ‘Tiny Towers’, :telephone => ‘4321′, :vat_number => ‘987654321′

dave = tiny_co.people.create :name => ‘Dave’, :address => ‘22 Acacia Avenue’, :telephone => ‘1234′

If we now look at our table we will see the following (some fields omitted because I’m lazy):

id type name company_id
1 Company Tiny Co null
2 Person Dave 1

The key is the “type” field we added. Rails treats this as one of its special “magic” fields and when you create an instance of Person or Company, Rails fills it out for you. Likewise, if you call AddressBookEntry.find(1) it will return you an instance of Company (not AddressBookEntry) - it uses the type to govern what it instantiates.

This means that Rails hides most of the mechanics of inheritance from you - you just write your models and they automagically do the right thing. There are some issues - your fixtures have to contain all descendants in a single file (in this case address_book_entries.yml) and it is perfectly legal to write dave.vat_number = ‘54321′ (as the vat_number field, which technically belongs to a Company, not a Person is still accessible to all AddressBookEntries).

But Rails has made inheritance in a database about as easy as I can imagine. There is a little bit more to inheritance - with ActiveRecord abstract classes, but that’s a story for another day.

Photo by spektator

Friday, May 25th, 2007

I love the song “Standing Here” by the Stone Roses (you may notice a Roses-bent to this blog). Not only does it have some of John Squire’s finest noodlings, great lyrics and fantastic work by Mani - it also includes one of my favourite bits of backing vocals in the world. A simple “ooh ooh” from Reni. That’s not the clever bit though. In the first verse there is no “ooh ooh”. In the second verse there is one “ooh ooh”. In the third, there are two “ooh ooh”s. I can still remember the first time I noticed it (months after I first heard the song). I pointed it out to my friends and they were all impressed too.

Just a tiny detail.

Hard to spot.

But once you’ve seen it you notice those same, tiny, details in their other songs. That craftsmanship, that attention to detail, is what made them great songwriters (at least till the Second Coming when Squire shoved Geffen’s money up his nose).

In the same vein, I have just spent twenty minutes adding a similar detail to our application. One that most people will never ever notice. But if they do, they will think “that’s nice” and for thirty seconds they will feel good about their choice to shell out cash on us. And the feature? It’s this:

Spotted it yet? How about here?

That’s right - the person object has a gender field and, based upon the gender, it displays the correct possessive - his or her (or their if not known) in the menus. Again, a tiny detail. But they all count.

Monday, April 23rd, 2007

I’m currently wrestling with a problem. My application has Attendees that either belong to PrivateCourses or Bookings. It uses a polymorphic association for this: has_many :attendees, :as => :attendable.

However, in both cases the UI is pretty much identical. So I figured I could set up routes like so:

map.resources :private_courses do | private_course |  private_course.resources :attendees, :name_prefix => ‘private_course_’endmap.resources :bookings do | booking |  booking.resources :attendees, :name_prefix => ‘booking_’endmap.resources :attendees

This gives me three options: either reference the attendee in the context of a PrivateCourse private_course_attendees_path(@private_course), in the context of a Booking booking_attendee_path(@booking) or all on its own attendee_path(@attendee). I was thinking I could examine the supplied parameters to figure out what the Attendable should be:

if !params[:booking_id].blank?  @attendable = Booking.find params[:booking_id]elsif !params[:private_course_id].blank?   @attendable = PrivateCourse.find params[:private_course_id]endif @attendable.blank?   @attendee = Attendee.find params[:id]else  @attendee = @attendable.attendees.find params[:id]  end

Looks good so far.

But it turns out my view code is turning into a conditional nightmare. Take the “new” form:

if @attendee.attendable.is_a?(PrivateCourse)  form_for :attendee, :url => private_course_new_attendee_path(@attendee.attendable) do | form |   …  endelse  form_for :attendee, :url => booking_new_attendee_path(@attendee.attendable) do | form |    …  endend

Of course, not only is this ugly but there needs to be code in the controller to set up the new Attendee’s Attendable. In which case I should just make the controller look like this:

@attendee = @attendable.attendees.buildif @attendable.is_a?(PrivateCourse)  render :action => ‘new_attendee_for_private_course’else  render :action => ‘new_attendee_for_booking’end

Yet as I went through this, I kept thinking that every single action needs the same conditional logic - actual form definitions aside, there is actually nothing that is shared between the two conditions.

So, my answer, barring a flash of inspiration, is “No, you cannot use the same controller in two places at once”.

Now I need to rework my body of code to have two controllers - PrivateCourseAttendees and BookingAttendees that both make use of a set of shared partials, probably in an Attendees folder.

Monday, April 23rd, 2007

One thing to watch out for, when using Markaby:

  link_to_remote ‘whatever’, :url => some_path(@something), :before => do_this, :complete => do_that

will not work.

Instead you need:

  link_to_remote ‘whatever’, :url => some_path(@something).to_s, :before => do_this, :complete => do_that

Spot the difference? The :url parameter has a .to_s appended on the end. Otherwise Markaby intercepts the call and eats the output.