LoginSignup
10

More than 5 years have passed since last update.

devise+mobyletteでiPhone/iPad/Android向けサイトに対応する

Last updated at Posted at 2014-01-24

mobylette gemを使ったUser Agent別のテンプレート切り替えを行う際、deviseとの連携部分で少し調整が必要だったので、そのメモです。

また、下記の内容を満たした前提で記述しています。

  • Rails + deviseでのPCからの基本的な認証環境は構築/実装済み
  • 認証に用いるmodelはUserモデル
  • mobile用のformatはmobile (mobyletteのデフォルトの設定)

gem の追加

mobylette gemの追加と最低限必要な設定はmobyletteのドキュメントを参考に追加する。

Gemfile
gem 'mobylette'
$ bundl install

ApplicationController へmobyletteのmoduleを追加

include Mobylette::RespondToMobileRequestsを行い、必要であれば、他の設定も追加する。

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  include Mobylette::RespondToMobileRequests
  # ...
end

ログイン画面へリダイレクトされるようにする

非ログイン時に、認証が必要な画面にアクセスした際にbefore_action authenticate_user!に引っかかるが、ログイン画面にはリダイレクトされない。
それを、ログイン画面にリダイレクトされるようにする。

  • Devise.navigational_formatsの設定を変更する。
config/initializers/devise.rb
Devise.setup do |config|
  # ...
  # config.navigational_formats = [:"*/*", "*/*", :html]
  config.navigational_formats = [:"*/*", "*/*", :html, :mobile] # :mobile を追加
end

ログイン画面へリダイレクトされた際のURLを調整

デフォルトの場合、http://example.com/sign_in.mobile のようにformat(.mobile)が付いてしまうため、付与されないようにする。

URLにformatが付与されるかどうかは、Devise::FailureApp#skip_format?によって判定されているので、下記のどちらかの対応をすると良いと思う。

  • Devise::FailureApp#skip_format? をオーバーライドする
  • CustomFailureAppクラスを作り、そのクラスのskip_format?で適切な処理を行う

Devise::FailureApp#skip_format? をオーバーライドする場合

config/initializers/あたりでskip_format?をオーバーライドしてやると良いと思う。
この例では、先述で設定したDevise.navigational_formatsを使って判定するように変更している。

config/initializers/devise_failure_app.rb
module Devise
  class FailureApp < ActionController::Metal
    def skip_format?
      # 元のskip_format?っぽく処理するなら↓な感じ
      # %w(mobile html */*).include? request_format.to_s
      Devise.navigational_formats.map(&:to_s).include? request_format.to_s     
    end
  end
end

CustomFailureAppクラスを作る場合

CustomFailureAppクラスを作る場合は、下記の2つの手順を行う。

  • CustomFailureAppクラスをautoload_pathsの通ったディレクトリに配置する
  • config/initializers/devise.rbfailure_appにCustomFailureAppを指定する

custom failre_appの作り方はここら辺を参考にするとよいかも。

lib/custom_failure_app.rb
class CustomFailureApp < Devise::FailureApp
  def skip_format?
    %w(mobile html */*).include? request_format.to_s
  end
end
config/initializers/devise.rb
Devise.setup do |config|
  # ...
  config.warden do |manager|
    manager.failure_app = CustomFailureApp
  end
  #...
end

ログイン認証成功後、特定のページにリダイレクトされるようにする

ログイン認証成功後devise/sessions/create.mobileなどのテンプレートをレンダリングしようとするが、大抵は認証直前のページやユーザーホームなどにリダイレクトしたいと思うので、その設定について。

必要なことは2つ。

  • ApplicationController#after_sign_in_path_for をdeviseの処理用に追加する
  • ActionController::Responder#to_mobile を追加する
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  include Mobylette::RespondToMobileRequests
  # ...
  private
  def after_sign_in_path_for(resource_or_scope)
    root_path # 例としてroot_pathへリダイレクト。redirect_toは不要でpathのみ返す
  end
end

大抵の場合to_mobileメソッドの追加はto_htmlへのaliasで問題がないので、config/initialize/mobylette.rbあたりにファイルを追加して行う。

config/initialize/mobylette.rb
ActionController::Responder.class_eval do
  alias :to_mobile :to_html
end

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10