A peek at the inner workings of Hashrocket

Posted on October 02, 2008

Recently the folk over at Hashrocket had another one of their famed 3-2-1 Launches - this time inviting as guest stars Tammer Saleh and Joe Ferris of another renowned Rails shop Thoughtbot. The application they worked on is called spot.us and is a community funded reporting tool.

The interesting thing about this project was that the source is freely available on Github for any Joe Bloggs to pour over (link). Not only that, but the client taped his reaction upon seeing the application for the first time: (link).

I had a quick looksee at the application, and what I saw blew me away - how'd they get so much done in such a short space of time?

Here's some of the stuff I noticed:

Used a good amount of boilerplate

Let's face it, a good chunk of every application is the same as the last application. Hashrocket have got a pretty decent suite of boilerplate code that they bung into the app to get started.

Upfront design

The week before the sprint, a bunch of stuff was checked in to do with user interface. this included:

  • Mocked up views,
  • All the images necessary for the design,
  • Javascript plugins

Basically, a good solid structure was in place so that the developers could go hard on concentrating on what they need to do, and not worry about big design decisions.

Not only that, but before any work had done, the application ''looked'' just like the final product, even if it didn't necessarily work yet.

Uber frequent commits

Take a look at the github network tree on the 24th, 25th and 26th - every 6 or so minutes something gets checked in. These folks checked in so fast it was as if their lives depended on it.

This is because they had small, perfectly formed units of work. Get the issue, work on it, check it in -> rinse and repeat. Also because of the hard-core frequent commits there were only 2 source code conflicts for the entire stretch!

Haml

I've studiously avoided haml throughout my Rails career because a niggling sensation at the back of my head doesn't feel comfortable with adding another layer of abstraction between me and the html. I've been bitten before with all the asp.net stuff Microsoft uses to hide html from .NET developers - and have since loved looking at plain old html since.

In spot-us all of the views are done in HAML.

After reading it for a bit, and getting my head around all that white space, I realised that the intent of the code was really easy to comprehend - I didn't have to wade through all that excess html junk we put up with. Instead the templates read like a page of code, filled with lovely methods and variables.

Used JQuery AND NOT Prototype

So, there's a weird little nasty part of me that believes you have to take sides in the great Javascript Framework War. Historically Rails developers belong to the Prototype/Scriptaculous faction - but all the hip cool kids these days seem to be gravitating towards JQuery.

Hashrocket instead decided to go with the best bits of both worlds by implementing bits of each. In their code you can see the old glory (some would say divisive) use of remote_form_for (which generates prototype Javascript) combined with the new hotness of JQuery plugins.

UPDATE Thanks to Ben Scofield for pointing out in the comments that the Hashrocket team actually use the jRails plugin. This plugin ensures that all the Rails javascript helper methods spit out JQuery rather than Prototype/Scriptaculous code. Find out more here.

JQuery has a nice little method:

jQuery.noConflict( );

This helps to make sure that jQuery doesn't conflict with other libraries - pretty sweet.

Done away with fixtures and used factory_girl

The Geniuses (Geni-i?) at Thoughtbot forego the whole fixtures route in favour of creating custom factories for their tests. The sweet little plugin that enables all this magic is called Factory Girl.

Here's an example - instead of calling out to a donation fixture, they just create a factory of a couple and populate it with the relevant attrbutes.

it "isn't valid if there is already a donation for that tip and user" do
  donation = Factory(:donation)
  duplicate = Factory.build(:donation, :pitch => donation.pitch, :user => donation.user)
  duplicate.should_not be_valid
  duplicate.should have(1).error_on(:pitch_id)
end

I'm not sure if Hashrocket started using factory_girl in this project because of their special guest stars, but it's not part of the standard boilerplate code.

Rspec view tests

Something hot and juicy about the hashrocket test suite was the inclusion of View Specs. RSpec view tests allow you to set expectations of your views in a nice sweet fashion without having to worry about the whole http round trip business.

For example:

describe 'profiles/show' do

  include ActionView::Helpers::AssetTagHelper

  before do
    assigns[:profile] = Factory(:user)
  end

  it "should display a thumbnail when available" do
    url = '/url/to/file.jpg'
    attachment = mock('attachment', :url => url)
    assigns[:profile].stub!(:photo).and_return(attachment)
    do_render
    response.should have_tag('img[src = ?]', url)
  end
end

Look ma, no controller!

Launch party

After a 3-2-1 Launch the hashrocket guys 'n' gals have an awesome big party. Judging from the tweets, it sounded like a fun time was had by all.

It got me thinking, most projects I've worked on don't specifically have an end point - they just kinda keep on going until they peter out and another project shows up. Having a definite line in the sand is a great motivating factor.

And finally

There's still a bunch of fiddly stuff to do on spot-us - but it's pretty amazing what they came up with.

Rats off to ya!

Rats off to ya!

Comments
  1. Matt DarbyOctober 02, 2008 @ 10:35 PM

    I happened be at Hashrocket last week during the spot.us 3-2-1 (AND Obie’s party!); and these guys are that good. They made my ten year experience look like two months.

  2. Glenn GillenOctober 03, 2008 @ 08:06 AM

    Ewww @ remote_form_for. Seriously, why not use the jQuery ajax form plugin or lowpro? The rails ajax/javascript helpers are evil, inserting JS inline in the HTML body.

  3. Ben ScofieldOctober 03, 2008 @ 11:52 AM

    Actually, they’ve installed the jRails plugin – it’s a drop-in replacement for Rails’ Prototype-based JavaScript helpers, so even the use of remote_form_for ends up using jQuery.

    They left the Prototype and script.aculo.us JS files in place, but those could’ve been deleted.

  4. Chris O'SullivanOctober 03, 2008 @ 01:14 PM

    Whoops, you’re right Ben – thanks for pointing that out

  5. Dan MayerOctober 03, 2008 @ 03:15 PM

    Very cool to see how others work through Ruby / Rails projects. I think celebrating victories is a great thing, which does get much harder when you have a project that is being released and worked on for months at a time.

  6. YossefOctober 03, 2008 @ 04:23 PM

    As someone who’s worked on two 3-2-1 projects before (neither of which are open-source [yet]), I can verify that factory_girl is not part of the boilerplate. We used Object Daddy (http://github.com/flogic/object_daddy) since we were more familiar with it (y’know, having written it).

  7. DigidaveOctober 03, 2008 @ 05:12 PM

    I’m actually the guy behind Spot.Us and this post just makes me tickled that (1. I went with Hashrocket and (2. We’ve been open about it.

    You might also find this post interesting: This was the week before the 3-2-1- week when I came out to work with Hashrocket breaking down the design into concrete stories that they could work on: http://blog.spot.us/2008/09/09/the-development-phase-has-begun/

  8. DigidaveOctober 03, 2008 @ 05:14 PM

    I should also add: This is a nonprofit and I believe – a good cause.

    So if any ruby on rails developers want to help out – as noted, it’s open source. Don’t hesitate to contact me (not hard to find www.digidave.org – I need all the Ruby-power I can get. Hashrocket is taking the lead, of course, but I’m sure they wouldn’t be against getting little bits of help.

  9. Ben McDonaldOctober 03, 2008 @ 06:08 PM

    Hey Chris,

    Thanks for the write up. It is much appreciated. As a business / resource manager here at Hashrocket I wanted to add a few things:

    1) Big hat tip to Joe and Tammer and all of Thoughbot for enabling this amazing mind / cultural sharing opportunity 2) We have used factory_girl prior to them showing up, but having Joe and Tammer made it a no-brainer for this project 3) Something that wasn’t mentioned too much in your post was about our process. Our move to Pivotal Tracker (http://www.pivotaltracker.com) 5 months ago, has allowed us to increase communication throughout the development process. In addition, the directive to the team is to deliver business value first and leaving features that could be considered pixel pushing or UI fixing until later. This makes for constructive discussions between the client and us, as consultants, resulting in web application that are adhering to the philosophies of Getting Real.

    The final point I wanted to make is that we are hiring. So if this sounds interesting to you please send an intro email along with resume to info (at) hashrocket (dot) com.

  10. VicOctober 04, 2008 @ 12:27 AM

    Can you explain a bit of how 3-2-1 works please?

    tia, Vic

  11. Giles BowkettOctober 04, 2008 @ 03:29 PM

    Most of this code is really nice and clean – impressively so – but what’s up with the TextMate URLs in the UI controller? Aren’t they just duplicating the Footnotes plugin? Why not just use Footnotes?

  12. Carmelyne ThompsonOctober 05, 2008 @ 07:42 PM

    Hi Giles, I am responsible for the txmt://open?url=file://file/to/open in the controller. I had a Hashrocket UI Comps System for 3-2-1 in place. It holds view files transposed to haml/css from its original graphic mock ups. This comps system bridges the implemented design/ui for the development process. You can view it in the Spot.Us app available from github. Just fire up the Spot.Us app and you can have an idea of Hashrocket UI Comps System for 3-2-1’s purpose via /ui.

    I’ve thought about Footnotes but at the time I was completing the supporting ui files, the basic textmate call was sufficient enough. The comps system is at it’s beginning implementation phase so it still in the works for more automation.