あおみかんのブログ

フリーランスのIT系エンジニア。ゲーム制作スタジオ4th cluster代表。

Rails5で簡単にモバイル/PCのビュー分岐を行う

最近、仕事で必要だったので。 だいたい以下の記事を元にしてるだけですが、ちょいサンプルコードなど含めて解説。

stackoverflow.com

元々は mobylette というgemを使おうとしたらRails5では(たぶん4でも?)コケちゃうので自前実装気味に済ませたって経緯がある。

想定するサービス

基本はレスポンシブだけどTOPページ等の一部の画面だけPC/モバイルでの分岐をしているようなサービス

方法

まず、以下のconcernsを作る。

# app/controllers/concerns/respond_to_mobile_requests.rb

require 'active_support/concern'

module RespondToMobileRequests
  extend ActiveSupport::Concern

  # Regexp From: https://gist.github.com/dalethedeveloper/1503252/931cc8b613aaa930ef92a4027916e6687d07feac
  MOBILE_REGEXP = /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/  
  included do
    before_action :variant_mobile

    def variant_mobile
      # The solution from: https://stackoverflow.com/questions/39495834/mobile-view-in-rails-5
      request.variant = :mobile if is_mobile_request?
    end

    def is_mobile_request?
      @_is_mobile_request ||= MOBILE_REGEXP.match request.user_agent
    end
  end

end

次に、描画を振り分けたいコントローラおよびそこのアクションで以下のようにする

# app/controllers/home_controller.rb

class HomeController < ApplicationController
  include RespondToMobileRequests

  def index
    if is_mobile_request?
      # モバイルの時だけの処理
    else
      # PCの時だけの処理
    end
    
    # 以下のコードでビュー振り分け
    respond_to do |format|
      format.html.mobile
      format.html
    end
  end
end

あとはビューファイルとして index.html.erb (※hamlでもslimでもご自由に)と index.html+mobile.erb を作れば、勝手にビューを振り分けてくれる。

もしCloudFrontのカスタムヘッダ( CloudFront-Is-Mobile-Viewer 等)とかを使いたければ、request.user_agentにmatchかけてる部分の代わりに request.headers['CloudFront-Is-Mobile-Viewer'] 等を見ればいいと思う。