rack-user_agent を作った
rack-user_agentという、User-Agentに応じていろいろな判定ができるメソッドを生やすRack::Request拡張を作った。
tagomorisさんのWootheeを使ってRack middlewareでUser-Agentをパースしておいて、
その結果に応じてrequest
から簡単にいろいろな情報を得られるようにしてある。
たとえばRailsだとGemfileにgem "rack-user_agent"
と書くだけで以下のように使うことができる。
class ApplicationController < ActionController::Base before_action :set_request_variant def index # example request.user_agent #=> "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 ..." request.device_type #=> :smartphone request.os #=> "Android" request.os_version #=> "4.3" request.browser #=> "Chrome" request.browser_version #=> "29.0.1547.72" request.from_pc? #=> false request.from_smartphone? #=> true end private # Action Pack Variants向け def set_request_variant request.variant = request.device_type # :pc, :smartphone, etc end end
なぜ便利か
例えばwootheeでスマホかどうか判定したかったら、ApplicationControllerとかに
def request_from_smartphone? Woothee.parse(request.user_agent)[:category] == :smartphone end
みたいなのを書く必要がある。けど、
request.from_smartphone?
で最初から書けたら便利だと思った。
Action Pack Variantsに使う
Ruby on Rails 4.1 Release Notes
Rails 4.1から、jsonやhtmlみたいなformatだけではなく、pcとかスマホのような条件によってテンプレートをスイッチできるようになった。
例えば、
app/views/projects/show.html.erb app/views/projects/show.html+phone.erb
みたいなビューがあったとき、request.variant
に:phone
が入っていればshow.html+phone.erb
が使われ、そうでなければshow.html.erb
が使われる。
jpmobileとかでできるやつ。
ただ、このrequest.variant
に何をセットするかはユーザーに委ねられていて、UAをパースして:phone
を入れたりするのは自分でやらないといけない。
そこを信頼できるUAパーサライブラリにまかせておけば、Railに乗ったまま楽にjpmobileみたいなことができて良いと思う。
作った背景、所感
最近触っているRailsアプリは、正規表現によるデバイスの判定を自前の正規表現で行っていた。
最近アプリ対応とかでその周りをいじることが多くなってきたんだけど、どんどん新しいデバイスが出てきてこれ保守するの無理だなと思った。
そこで、多言語に対応しているからいろんな人にメンテされそうなwootheeにUAのパースを任せることにした。
UAのパーサ保守するの大変なのでなるべく多くの人が保守してるやつを使って助け合いたい。