25 October 2012
Rails Rumble Recap
Last weekend I participated the 2012 Rails Rumble.
The Rumble is programming competition where teams of up to 4 people have 48
hours to build a web application with Ruby on Rails.
My teammate @joshowens had actually won the
contest in 2007 with his recipe building application “Tasty Planner”. In the
years since, I got the impression that the field had grown quite a bit. When I
heard that there were 500 registrations this year, I was wondering what I was
getting myself into.
After the fact though, my attitude is that this competition is totally
winnable. If you know how to play the game, a decent idea and good planning
beforehand can take you a long way.
ShareBelt
The idea for the application was hatched by Josh. It’s a tool for encouraging
sharing on website or blog. It displays a single, prominent share option onto
a web page, tailored to each visitor based on where they came from. That
message and share button floats in a bar at the top or bottom of any page.
It’s called “Sharebelt”. If a user arrives at your
ShareBelt-enabled blog from Twitter, they might see a message at the top of
the page: “Hi I see you came from Twitter, why not [Retweet] this?”, with a
button allowing them to do so.

Our initial prototype would recognize visitors from, and allow sharing to
Twitter and Facebook. Our backend administration application would capture
statistics, and report on daily Sharebelt impressions, clicks, tweets, shares,
and likes for our users.
ShareBelt Implementation
There was a pretty obvious separation in the technology required to make
ShareBelt happen, so splitting the work between two developers was pretty cut
and dry.
The ShareBelt itself is implemented on the client-side with Javascript. A
ShareBelt account holder receives a snippet of html code to paste into their
website, anywhere they want the ShareBelt to pop in. The snippet contains an
id that represents the site of the account holder in the ShareBelt system, and
a script tag that loads the main Javascript code from a location on the
ShareBelt server.
The ShareBelt backend is the Ruby on Rails piece. It provides routes for the data
capturing, and an administration interface for ShareBelt clients. Data is
captured when users take actions like tweeting or liking. The administration
interface allows ShareBelt users to set up and see reporting and analytics on
any number websites.
Technical Challenges
As the main Javascript developer, my first challenge was wrestling with cross-
domain Ajax requests. The problem occurs any time javascript code running on
site attempts to call out to a location outside the current domain. Browsers
will prohibit these kinds of Ajax requests, but the workaround is so common
that it makes the restriction quite trivial.
Although browsers will restrict the Ajax call, they will happily load and run
Javascript at a location set in the “src” attribute of a script tag. The
strategy is then to, instead of calling out with Ajax, to call out with a
script tag. When you append the script tag into a document, it gets fetched
and executed.
injectScript: (d) ->
script = d.createElement("script")
script.setAttribute("src", "https://endpoint.com")
d.head.appendChild(script)
In order to do something with what that call returns, the endpoint needs to
return JSONP. Executed JSONP calls a method on the client-side that has been
defined by you, most likely in the same piece of Javascript that injected the
script tag. For example, JSONP returned from the server might look something
like:
executeResponse({"some": "JSON", "data": "here"}).
That piece of code is returned from your endpoint, and evaluated on the
client-side where you have previously defined the executeResponse method. It’s
a little tricky, Wikipedia, Dino
Esposito, and my partner @joshowens are
all good resources on this subject.
That hurdle surpassed, I was able to build enough infrastructure to load some
appropriate HTML and Javascript from the ShareBelt server based on where the
visitor had come from, and capture an impression on the backend.
The bulk of that returned code is publicly-provided snippets for loading
Facebook and Twitter sharing widgets. So, at this point in the project, I
could render the belt and widgets, and people could do the sharing. But how
was I going to capture and record the actions that users took with these
third-party tools?
Luckily, this didn’t turn out to be as much of a challenge as I expected. I
found that both Twitter and Facebook platforms provided a pretty full featured
system for triggering callbacks on events. Twitter’s is called Web
Intents and allowed me to trigger code
on a click of the Tweet button, and the Tweet itself. Facebook’s Like and
Share callbacks I configured via the FB.Event.subscribe() API. Read Facebook’s Javascript
SDK page to get
started with that.
What kind of code did I want to execute with these callbacks? More cross
domain Javascript requests, of course! Once you recognize the script injection
pattern, you see it everywhere. In fact, both of the publicly-available
Twitter and Facebook snippets are themselves using script injection to fetch
and render their sharing widgets ( and do who knows what else ).
48 Hours
Time did not turn out to be as big of a challenge as I expected with respect
to coding. I don’t think my code is completely horrible, but I did take some
shortcuts. The scope of the minimum viable product we laid out were
manageable.
I did feel some urgency and so I didn’t test drive. It felt ok, until it
didn’t. At some point the discomfort of cowboy coding overtakes the speed
benefit you get from it. A little more than halfway through the competition,
about 10 o’clock on Saturday night, I spent my last couple of hours putting in
Jasmine and refactoring the bulk of my
Javascript code into a classes that I could test. I learned things. It became
apparent from this experience why it’s bad to access the document object
directly from within a class. I couldn’t test the code in the absence of a
document object. Mocking and passing the document into the class broke
dependency, and allowed me to take control. It reminded me of what I like so
much about coding Javascript. Objects are so easily mockable and re-shapeable.

Time was a factor in design and marketing.
@nerdyllama, our designer was not able to get
much direction from us, and was not able to iterate as quickly as we could. We
failed to effectively plan for setting up demonstrations of the product in
action, and we even failed to put Sharebelt on the Sharebelt landing page! Our
ranking definitely suffered as a result of poor planning in the presentation
of our application.
New-to-Me Tools
I’m used to Heroku, but the Rumble was hosted on Linode, and we did deploys
with capistrano. We were using Campfire to keep in
constant contact, and one of the first things Josh did was to set up
capistro-campfire.
Whenever a team-member did a deploy, campfire posted a link to the git commit
so we could see the new code and diffs. With large teams or large projects,
this might be overkill. But in a small team working on small overlapping
pieces of code on a tight schedule it was really, really handy.
The other cool tool was the NVD3 charting library. The
interface reminded me a lot of Highcharts, I
can’t say I prefer one to the other. The series plotting made a little more
sense to me out of the box, and NVD3 might have a slight edge on the
presentation as well. I’ve been impressed by both, but if you’ve had any
issues with Highcharts give NVD3 a try.
Rumble Regrets
As I mentioned before, a lack of a plan for presenting the product is my
biggest regret. We have a working application that touches on some pretty
interesting and relevant technologies, but we left it up to the judges to
figure out how to use it. The irony is that most of this most essential
planning work could have been done legally in the weeks leading up to the
competition. Live and learn!
Conclusion
When the clock struck 8PM on Sunday night, I took a deep breath. The feeling
was surreal. The whole weekend had happened, I had learned a ton of new stuff,
and I had a pretty tangible product sitting in front of me. I had a strong
feeling of satisfaction and accomplishment. I would definitely do this again.
Rumble applications have a history of becoming real products. As for
Sharebelt, we plan to get it in front of people and
continue development. Is it going to make a million-dollars? I have no clue.
But thanks to the motivation and focus provided by the competition, it’s more
than an idea, which is where 99% of products begin and end. Rumble on!