A peek at the inner workings of Hashrocket
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!