Skip to content
By Glen Crawford

Variants With Ruby on Rails

A quick post to talk about a new feature in Rails 4.1: Action Pack variants.

Variants allow your app to easily serve different templates in different cases, for example, different templates for phones, tablets and desktops. In other words, variants allow you to arbitrarily respond with different templates within the same MIME type (e.g. HTML).

To use Action Pack variants, you set the request.variant to a symbol for the name of the variant in a controller, probably in a before_action. You can then respond to each of those variants in your actions in the same way that you respond to different formats.

Example: different templates for devices

Using the different devices use case as the obvious example, we can set the request variant like so (using the awesome browser gem):

class ApplicationController < ActionController::Base
  before_action do
    if browser.tablet?
      request.variant = :tablet
      request.variant = :phone

Now when no template can be found for a particular action, you will see something like :variants => [:tablet] along with the formats and handlers.

Now you can go ahead and add new templates to your app/views/* directory, one for each variant. The variant is specified in the file name with a + symbol, such as show.html+tablet.erb. Your views directory for a resource would now look something like this:

glen@~/projects/rails_app > ls app/views/graphs/
-rw-r--r--  1 glen  staff    0 30 May 14:47 show.html+tablet.erb
-rw-r--r--  1 glen  staff    0 30 May 14:47 show.html+phone.erb
-rw-r--r--  1 glen  staff    0 30 May 14:47 show.html.erb

With the show.html.erb file being a catch-all for when there is no request.variant is set, or when there is no matching template for the request.variant. So you probably wouldn't have a desktop variant; you would likely just let your apps render the catch-all show.html.erb template for desktops.

The correct template will now be rendered for each variant. You don’t need to explicitly specify each format in a respond_to; if a template for the variant exists, it will be rendered.

As for partials, if a template attempts to find a partial and request.variant is set, then a partial with the variant in the file name will be prioritised and rendered if one is found, and the non-variant partial will be rendered if not. For example, if request.variant is set to :v2, then <%= render "sidebar" %> would render _sidebar.html+v2.erb if it exists, and _sidebar.html.erb if it doesn't. However, if request.variant is not set, only _sidebar.html.erb would be tried, and not the v2 variant.

You can also execute variant-specific code in your actions within the standard respond_to block, like so:

class GraphsController < ApplicationController
  def show
    respond_to do |format|
      format.html do |html| do
          # Do something specific for phones here.

There is also a shorthand for this, which I'll let you read for yourself.

Another example: beta testers

Rendering different templates for different types of devices is the typical example use for variants, but there are a lot of other cool uses, such as rendering different templates for different classes of users, for example, beta testers of a new design for your site.

Template files:

glen@~/projects/rails_app > ls app/views/graphs/
-rw-r--r--  1 glen  staff    0 30 May 14:47 show.html+v2.erb
-rw-r--r--  1 glen  staff    0 30 May 14:47 show.html.erb

And setting the variant:

class ApplicationController < ActionController::Base
  before_action do
    request.variant = :v2 if current_user.beta_tester?

It’s that simple. Just a couple of lines of code is all that you need to render an entirely different set of templates to a different group of users.


And that's all there is to it. Variants are an extremely powerful new feature of Rails, particularly because of their flexibility, and the fact that more and more companies are building mobile interfaces for their site. While the obvious use case for variants (and what you will find in all the blogs and articles on the topic) is rendering different templates for mobile and desktop users, the feature itself is agnostic from any particular use case, allowing you to use variants for any reason you can think of.

Popular Articles by Our Team

Our expert team of designers and developers love what the do and enjoy sharing their knowledge with the world.

We Hire Only the Best

reinteractive is Australia’s largest dedicated Ruby on Rails development company. We don’t cut corners and we know what we are doing.

We are an organisation made up of amazing individuals and we take pride in our team. We are 100% remote work enabling us to choose the best talent no matter which part of the country they live in. reinteractive is dedicated to making it a great place for any developer to work.

Free Community Workshops

We created the Ruby on Rails InstallFest and Ruby on Rails Development Hub to help introduce new people to software development and to help existing developers hone their skills. These workshops provide invaluable mentorship to train developers, addressing key skills shortages in the industry. Software development is a great career choice for all ages and these events help you get started and skilled up.

  • Webinars


    Webinars are our online portal for tips, tricks and lessons learned in everything we do. Make the most of this free resource to help you become a better developer.

    Learn more about webinars

  • Installfest


    The Ruby on Rails Installfest includes a full setup of your development environment and step-by-step instructions on how to build your first app hosted on Heroku. Over 1,800 attendees to date and counting.

    Learn more about Installfest

  • Development Hub

    Development Hub

    The Ruby on Rails Development Hub is a monthly event where you will get the chance to spend time with our team and others in the community to improve and hone your Ruby on Rails skills.

    Learn more about Development Hub

Get the “reinteractive Review” Monthly Email