A couple of months ago I released a small gem for generating Gmail style avatars called avatar_magick. The gem is a plugin for Dragonfly and has a couple of different use cases, the most common of which is being able to generate a default avatar in the event that a user doesn’t upload their own. This is a common practice in applications with user accounts and it can be handled in different ways. The simplest and probably most commonly used is some form of the head-shoulders silhoutte.
This works well in certain cases but is less than ideal in situations where multiple avatars are displayed on a single page (e.g. a comments feed). In such cases, it’s best if the avatars have some variation. For example, Github uses indenticons, small pixel sprites that are generated using a hash of the user’s ID. Basecamp, on the other hand, will randomly assign one of their awesome custom painted avatars. Another great approach, and the inspiration behind avatar_magick, is Gmail’s use of initial avatars - a single letter representing the sender’s name centered on top of a colourful background. This small change can have a positive impact on user experience.
In this guide, I’ll cover how to use Dragonfly and the avatar_magick plugin to add this style of initial avatars to an existing Rails project.
For those unfamiliar with Dragonfly, it’s a great library for handling images and other attachments but also provides on-the-fly image processing thanks to the included
image_magick plugin. Dragonfly can be used as an alternative to paperclip or used in conjunction to generate on-the-fly thumbnails. By also including the
avatar_magick plugin, we can extend this functionality further by allowing us to generate initial avatars like those described above.
For the purposes of this guide, the Rails project I’ll be working with is a simple application for managing contacts. The fully implemented source is available here. Please use it as a reference.
Adding and configuring dragonfly and avatar_magick
The first step is adding the
avatar_magick gems to your application. Open your
Gemfile and add the following before running
Next, generate the dragonfly initializer
This will create a
dragonfly.rb file within the
config/initializers/ directory. Open this file and add the following
directly below the
plugin :imagemagick line. With Dragonfly and avatar_magick configured, let’s generate some avatars.
To generate the actual avatars, we’ll define a custom endpoint to control the size, background colour, and text of our avatars. Within
routes.rb, add the following
Now, URIs that match the above route will delegate to Dragonfly which in turn will use the
avatar_magick plugin to generate an initial avatar. For example, visting
http://localhost:3000/avatar/250/d81b60/bart in development would produce the following avatar
Acts as Avatarable
As mentioned previously, our example Rails application manages contacts. For each contact, we’d like to be able to set the name, email, phone number, and photo. If a photo isn’t provided, the application should default to an initial avatar. To handle the bulk of the work, we’ll create an
Avatarable concern which we can then mixin to any model we’d like and override as necessary.
Let’s step through the above to get a better understanding of how this all works. At the top, we define a constant that holds an array of background colours. While
avatar_magick works with any colour (for both text and background), I’ve decided to limit my choices to Material Design Colours that work well with white text. A similar approach can be used if you need to conform to a particular color scheme.
Next we define several methods that are used to construct the paramaters needed to generate the avatar, mainly size, colour, and text. The
avatar_text method will need to be implemented in whatever class includes this concern and we ensure this by having it raise an exception in the event that it isn’t. While the
avatar_size method is self explanatory, the
avatar_color method requires a bit of an explanation.
We don’t care which colour is chosen for the avatar but we need it to be consistent. In other words, if the initial call to
'43a047', subsequent calls should produce this same value. If we simply call
AVATAR_COLORS.sample, a random but different value will be returned everytime. To ensure consistency, we use the
Zlib library to calculate the crc checksum of a string returned by
avatar_param (a stringified version of the model’s
id in our case). The calculated checksum is an integer that will be identical for strings of equal value. Finally, we perform a modulo operation on the checksum to ensure we’re in the bounds of our array of colours.
To construct the actual URL for our avatar, we define
avatar_url which simply delegates to
Rails.application.routes. Visiting this URL will produce an image like the one shown above.
Hooking it all up
Avatarable concern in place, it’s time to hook everything up. We’ll start by including the concern within our Contact model. This will mixin all the required
avatar_ methods; however, we’ll need to implement
avatar_text as noted above. Our completed Contact model looks like this
Since we want to show either the uploaded photo or the avatar, we’ll create a simple view helper to handle this for us
We can then use this anywhere we need to display a contact’s avatar
That’s it! We now have great looking default avatars for our contacts along with the ability to upload a custom photo.
Bonus - Paperclip Attachments
If instead of Dragonfly, your app uses paperclip to handle image attachments, you can still use
avatar_magick to provide default avatars. Take a look at the paperclip-attachments branch to see how this is accomplished.
Similarly, if you want to only display the initial avatars and have no need for handling attachments, take a look at the master branch to see how to use
avatar_magick without using Dragonfly’s attachment handling feature.