mobylette gemを使ったUser Agent別のテンプレート切り替えを行う際、deviseとの連携部分で少し調整が必要だったので、そのメモです。
また、下記の内容を満たした前提で記述しています。
- Rails + deviseでのPCからの基本的な認証環境は構築/実装済み
- 認証に用いるmodelは
User
モデル - mobile用のformatは
mobile
(mobyletteのデフォルトの設定)
gem の追加
mobylette gemの追加と最低限必要な設定はmobyletteのドキュメントを参考に追加する。
gem 'mobylette'
$ bundl install
ApplicationController へmobyletteのmoduleを追加
include Mobylette::RespondToMobileRequests
を行い、必要であれば、他の設定も追加する。
class ApplicationController < ActionController::Base
include Mobylette::RespondToMobileRequests
# ...
end
ログイン画面へリダイレクトされるようにする
非ログイン時に、認証が必要な画面にアクセスした際にbefore_action authenticate_user!
に引っかかるが、ログイン画面にはリダイレクトされない。
それを、ログイン画面にリダイレクトされるようにする。
-
Devise.navigational_formats
の設定を変更する。
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
を使って判定するように変更している。
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.rb
でfailure_app
にCustomFailureAppを指定する
custom failre_appの作り方はここら辺を参考にするとよいかも。
class CustomFailureApp < Devise::FailureApp
def skip_format?
%w(mobile html */*).include? request_format.to_s
end
end
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 を追加する
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
あたりにファイルを追加して行う。
ActionController::Responder.class_eval do
alias :to_mobile :to_html
end