Last Updated: February 25, 2016
· sergiotapia

How to use Rails 4.1 ActionPack Variants.

How to use Rails 4.1 ActionPack Variants.

Rails 4.1 released a little while ago and came out with a fantastic new feature I think a lot of responsive web developers are going to flex.

It's called Variants. ActionPack Variants.

What does it do?

I allows you to create different views for different device formats - such as mobile phones, tablets and desktops.

# /app/views/home/index.html.erb
# /app/views/home/index.html+phone.erb
# /app/views/home/index.html+tablet.erb

Why is this useful?

This is tremendously useful because you can now serve a much slimmer
version of your view to mobile devices, instead of just hiding the
elements using CSS using media queries.

Hidden elements still load and need to come down 'the wire' - using
Variants it's much easier than before to serve up lean and mean views
to mobile devices.

Example self-contained application:

You can find a simple Rails application that uses the code in this example here:

Create a helper function in your application_controller.

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  before_action :detect_device_format


    def detect_device_format
      case request.user_agent
      when /iPad/i
        request.variant = :tablet
      when /iPhone/i
        request.variant = :phone
      when /Android/i && /mobile/i
        request.variant = :phone
      when /Android/i
        request.variant = :tablet
      when /Windows Phone/i
        request.variant = :phone

Respond to the variant set inside of your controllers.

class HomeController < ApplicationController
  def index
    respond_to do |format|
      format.html          # /app/views/home/index.html.erb    # /app/views/home/index.html+phone.erb
      format.html.tablet   # /app/views/home/index.html+tablet.erb

Finally, create your three separate views.

<!-- Inside the index.html.erb -->
<p>This is from desktop page view.</p>

<!-- Inside the index+phone.html.erb -->
<p>This is from phone page view.</p>

<!-- Inside the index+tablet.html.erb -->
<p>This is from tablet page view.</p>

That's a wrap. As you can see it's quite simple, and very flexible.

I would recommend crafting two separate views when needed:

  • The desktop/tablet view.
  • The mobile phone view.

Have the mobile phone view call smaller images and fewer html elements. Instantly make your views faster.

Testing this out locally without a device?

You're going to need to use a user-agent switcher to see the various
views. I recommend:

For Firefox:

For Chrome: