🦧

deviseにフレンドリーフォワードを実装する方法

2021/04/28に公開

環境

Ruby 2.6.6
Rails 6.0.3
Devise 4.7.3

実装(Userモデルが例)

# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  before_action :store_user_location!, if: :storable_location?
  .
  .
  .
  private

  def storable_location?
    request.get? && is_navigational_format? && !devise_controller? && !request.xhr?
  end

  def store_user_location!
    store_location_for(:user, request.fullpath)
  end
end

HTTPリファラ情報を送信しないブラウザも存在するため、リンク元のURLを取得する方法としてはrequest.refererを使用するのではなくsessionを使用した方が堅牢性が高くなります。


そこで以下の条件が当てはまらない場合にのみsessionに現在のfullpathを保存します。

  • getメソッドでない場合
  • deviseコンとローラーで表示される画面の場合(ログイン画面など)
  • Ajaxでの遷移の場合


# sessions_controller
class Users::SessionsController < Devise::SessionsController
  protected

  def after_sign_in_path_for(resource_or_scope)
    stored_location_for(resource_or_scope) || super
  end
end

さらにログイン後のpathを先ほどのsessionに保存したpathにオーバーライドします。あとは好きなアクションのbefore_actionコールバックにauthenticate_user!メソッドを使えばフレンドリーフォワーディングが完成です。

参考

How To: Redirect back to current page after sign in, sign out, sign up, update

Discussion