sessionを使い遷移元の1つ前のページに戻る方法


こんな人におすすめ

こういうことがしたい人。
戻るボタンを押してブラウザの2つ前のページに戻りたい。

環境

ruby 2.5.1
Rails 5.0.7.2

さっそく結論

sessionを使いましょう。

今回の経緯

  • 購買機能のあるWEBサイトを作成していた(payjpを利用)
  • 商品の詳細を表示してそのまま購入できる機能を持たせた
  • ただしクレジットカードを登録していない場合は以下のページ遷移としたい

※上の図の左の1から右の3へいく流れ

1.商品の確認ページで購入ボタンを押す
2.購入完了の前にクレジットカード登録ページ遷移してカード登録をする
3.『この情報で登録したよ』という確認のページに遷移する

問題点

戻るボタンを押すとひとつ前のカード登録ページに戻ってしまう
(正確にはカード登録ページからリダイレクトされるページに戻ってしまう)

【解決策】 sessionを使って遷移元の1つ前のリファラーを保持しよう

全体像

class CardsController < ApplicationController

  require "payjp"

  before_action :sign_in_required
  after_action :session_clear, only: [:show]

  def new
    session[:previous_url] = request.referer
  # 〜以下省略〜
  end

  def pay
    # 〜省略〜 カード登録のコードが入ります
  end

  def delete
    # 〜省略〜 カード削除後のコードが入ります
  end

  def show 
    @session = session[:previous_url]
    # 〜省略〜 カード登録後のコードが入ります
  end

  private

  def sign_in_required
    # 〜省略〜 ユーザー登録していない場合はユーザー登録ページに遷移するコードが入ります
  end

  def session_clear
    session[:previous_url].clear
  end

end

今回使ったcontroller内のコード抜粋

初めてカード登録をする際に定義しているnewアクションに記述

# URLを保存する処理
# sessionにひとつ前のリファラーをいれる 
session[:previous_url] = request.referer

:previous_urlというのはdeviseを入れている場合は記述するだけで利用できます。
request.refererというのは、ひとつ前のURL(つまり遷移元URL)を取得するものです。

カード登録確認画面のshowアクションに記述

# sessionの中からURLを取り出してリダイレクトさせる
@session = session[:previous_url]

viewで使い回したいので代入したものにさらに代入してインスタンスを生成します。

新しくsession_clearアクションを記述してafter_actionで呼び出す

# sessionをクリア
session[:previous_url].clear

蓄積されたsession解放してあげたほうがセイキュリティ上でも良いとされています。

これで、理想の遷移元に戻ることができました。

おわり。