技術ブログ

(技術系中心)基本自分用備忘録なので、あくまで参考程度でお願いします。

フレンドリーフォワーディング

フレンドリーフォワーディング

リダイレクト先をユーザーフレンドリーにします。

Ruby on Rails チュートリアル:実例を使って Rails を学ぼう

発生内容

① ログインしていないユーザーがeditページを開く
② ログインしてくださいと注意勧告される
③ ログインする
④ 問答無用で自分のプロフィールページに移動させられてしまいます

この時、もともとユーザーはeditページを開こうとしていたので、editページにリダイレクトしてあげるのが最適解。
ですので、リダイレクト先は、ユーザーが開こうとしていたページにしてあげるように改造します。

実装方法

① 一時的に行きたいURLを覚えてく。
② リクエストされたURLが存在する場合はそこにリダイレクトし、ない場合は何らかのデフォルトのURLにリダイレクトします。  
シンプルですね!

まずは① 一時的に行きたいURLを覚えてく。

module SessionsHelper
  .
  .
  .

  # アクセスしようとしたURLを覚えておく
  # request.original_urlでリクエスト先が取得できます
  def store_location
    session[:forwarding_url] = request.original_url if request.get?
  end
end

store_locationメソッドでは、 リクエストが送られたURLをsession変数の:forwarding_urlキーに格納しています。ただし、GETリクエストが送られたときだけ格納するようにしておきます。

urlの取得の時にリクエストオブジェクトを使用。 railsdoc.com

ログインしてくださいと注意勧告された時にURLを保存

app/controllers/users_controller.rb
  .
  .
  .

    # ログイン済みユーザーかどうか確認
    def logged_in_user
      unless logged_in?
        ** store_location **
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end

② リクエストされたURLが存在する場合はそこにリダイレクトし、ない場合は何らかのデフォルトのURLにリダイレクトします。  

フォワーディング自体を実装するには、redirect_back_orメソッドを使います。リクエストされたURLが存在する場合はそこにリダイレクトし、ない場合は何らかのデフォルトのURLにリダイレクトします。  

module SessionsHelper
  .
  .
  .

  # 記憶したURL (もしくはデフォルト値) にリダイレクト
  def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    session.delete(:forwarding_url)
  end

これをログイン成功時のメソッドcreateのコードの中にいれてあげる。

app/controllers/sessions_controller.rb
  .
  .
  .


  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      params[:session][:remember_me] == '1' ? remember(user) : forget(user)
      ** redirect_back_or user **
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

これで完成。