Rails - フレンドリーフォワーディング
はじめに
詳細は、Rails tutorial 第10章の「フレンドリーフォワーディング」を参照。
https://railstutorial.jp/chapters/updating_and_deleting_users?version=5.1#sec-friendly_forwarding
Tutorialですぐに理解できなかったので復習用としてまとめてみました。
理解できれば簡単ですが、初見で見ると実装が何やっているのか分かりづらい...
求める仕様
未ログイン状態で権限のないページをリクエストした場合を想定。
この場合、下記のような仕様にしたい。
- まず、ログインページに遷移する
- 次に、ログインが完了後、先ほどリクエストしたページへ遷移する
つまり、通常のログイン時と同じ遷移先ではなく、
ユーザーがログイン前に見たかったページに遷移させるようにする。
上記を実現するために必要なメソッド
アクセスしようとしたURLを覚えておくメソッド(store_location)
ログイン済みか判定するロジックにおいて、未ログインならば store_location が呼ばれ、
ユーザーが見たかったページを一旦覚えておく。
覚えておいたページへリダイレクトするためのメソッド(redirect_back_to)
ログイン時のリダイレクト先として redirect_back_to を呼び出し、
store_locationで覚えているURLが存在すればそちらに遷移。
存在しない場合は通常のログインの場合と同じURLへ遷移。
SessionsHelperにメソッドを追加
次の2つのメソッド
# アクセスしようとしたURLを覚えておく def store_location session[:forwarding_url] = request.original_url if request.get? # GETリクエストの時のみ end # 覚えておいたページへリダイレクト def redirect_back_or(default) redirect_to(sessions[:forwarding_url] || default) session.delete(:forwarding_url) end
store_location は、ログイン済みか判定するロジックにおいて呼ばれる
class UsersController < ApplicationController before_action :logged_in_user, only[:edit, :update] . . private . . def logged_in_user unless logged_in? store_location # ★ここで呼ばれ、未ログイン状態の時に遷移先を覚えておく flash[:danger] = "ログインしてください。" redire_to_ login_url end end end
redirect_back_or は、ログインに成功した直後に呼ばれる
store_locationで覚えているURLが存在すればそちらに遷移。
存在しない場合は通常のログインの場合と同じURLへ遷移。
メソッドの名称がいいですね。引数をorの目的語(補語?)にしている。
class SessionsConroller < ApplicationController . . . def create user = User.find_by(email: params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) log_in user redirect_back_or user # ★ログインに成功した場合、遷移先を決定する else flash.now[:danger] = 'メールとパスワードの組み合わせが正しくありません。' render 'new' end end . . . end