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 elsif browser.mobile? request.variant = :phone end end end
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| html.phone do # Do something specific for phones here. end end end end end
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? end end
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.
Conclusion
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.
Latest Articles by Our Team
Our expert team of designers and developers love what the do and enjoy sharing their knowledge with the world.
-
The Axioms of Software Development – Part 5
-
Is it worth upgrading your Rails application?
-
The Axioms of Software Development - Part 4
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.