Add Gravatars to your Rails Application

Posted on October 27, 2008

I wanted to add Avatars to my new project whatiwantforxmas.com but it felt like too much hard work. So, I took a leaf out of githubs book and used Gravatars.

Gravatars are an already pre-packaged avatar system, all bright and shiny and ready to be added to your application.

If you haven’t got a Gravatar do me a favour, go over to gravatar.com and signup

It’s ridiculously easy to put in your app!

I use Scott Woods nice little Gravatar plugin – you can install it in your Rails app thusly:
script/plugin install svn://rubyforge.org/var/svn/gravatarplugin/plugins/gravatar
Here’s how you use it, bung this into your view (where user is an object that has an email attribute):
gravatar_for(user)

And BOO YA – you’ve got an instant gravatar image on your page!

You could also call by passing in an email address (but it’s not so sexy):
gravatar(user.email)
gravatar("jim@banana.com")
You can even set which size you want! (As in this case 50px x 50px)
gravatar(user.email, :size => 50)

“But wait! What if the user doesn’t HAVE a Gravatar?!” Well, then a default image is used instead. Typically something nasty like this:

But dry your eyes, all is not lost. You can set your own default Gravatar! When you call the Gravatar method just pass in a :default param pointing to the default image you want to use.
gravatar_for(user, :size => 50, :default => "http://www.whatiwantforxmas.com/images/avatars/santa/santa-50.png")

I wasn’t into the scaling of the default images though, so I wrote this little snippet of code so that you can have a separate default image for each Gravatar size you want. This ensures that I only use Gravatars that are 25, 50 or 70px (the sizes that I have default images for).

Copy this code into a file in your lib folder, and don’t forget to ‘require’ it in an initializer.

module GravatarHelper
  module PublicMethods

    AVATAR_SIZES = [25, 50, 70]

    def gravatar_for_with_default(object, options={})
      options[:size] ||= 25      
      options.merge!(:default => "http://www.whatiwantforxmas.com/images/avatars/santa/santa-#{options[:size]}.png")      
      # sizes are 25, 50 and 70
      raise RuntimeError, "Incorrect size for Avatar" unless AVATAR_SIZES.index(options[:size])    
      gravatar_for_without_default(object, options)
    end
    alias_method_chain :gravatar_for, :default
  end
end
And then I just need to call it like this:
gravatar_for(user, :size => 50) # This will use my default avatar

PS Yeah, I know I know – my blog doesn’t use Gravatars yet…

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!

Using assert_select on strings

Posted on October 01, 2008

Question:

assert_select is awesome for testing dom objects – but it relies on using the standard rails response cycle. How can I use assert_select on to find dom elements in a standard string?

Answer:

Stub the response object!

def test_big_selector_helper
  # the response requires a content_type - just set it to "text" 
  @response.stubs(:content_type).returns "text" 

  # big_element_selector is the helper method I'm testing in this instance
  # replace with the string that you want to test
  @response.stubs(:body).returns big_element_selector

  # now you can use assert_select
  assert_select "ul" do
    assert_select "li", :count => 3
  end
end