ホーム DoRuby devise ログイン後のリダイレクトについて(POST編)

devise ログイン後のリダイレクトについて(POST編)

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Rails の Devise でログイン後にログインする直前のPOSTリクエストにリダイレクトさせます。

 目標

RailsでPOSTリクエストではリダイレクトできないため、deviserログイン後はGETリクエストのみリダイレクトできます。

下記の場合、お気に入り登録が出来ないし、お気に入り一覧にリダイレクトできないです。

未ログイン⇒商品詳細⇒お気に入り登録(POST)⇒ログイン画面⇒ログインする⇒お気に入り一覧

 対策

POSTなので、直接遷移が出来なくて、after_login_to_postを作成して、その後自動サブミットすれば、POSTリクエストにリダイレクトを実現します。

動き:

未ログイン⇒商品詳細⇒お気に入り登録(POST)⇒ログイン画面⇒ログインする⇒after_login_to_post⇒真っ白ページ(自動サブミット)⇒お気に入り一覧

 セッションに POST リクエストのパラメータを保存

POSTリクエスト中で、POSTリクエストのパラメータ、コントローラ、アクションをセッションに保存します。

class CustomersFavoritesController < ApplicationController
  before_action :authenticate_customer!, except: :create
  def create
    if current_customer.signed_in?
      current_customer.favorites.create(product_id: params[:id]) unless current_customer.favorites.find_by(product_id: params[:id])
      redirect_to action: :index
    else
      #セッションに POST リクエストのパラメータを保存
      session[:after_login_to_post] = {
        controller_name: controller_name,
        action_name: action_name,
        params: { id: params[:id] }
      }
      redirect_to new_customer_session_path
    end
  end
end

 ログイン後のリダイレクトをカスタマイズ

ログイン後、セッションにPOST情報があれば、after_login_to_post_pathにリダイレクトさせます。

class CustomersSessionsController < Devise::SessionsController
  # ログイン後、リダイレクト先メッソドafter_sign_in_path_forをオーバーライドする。
  def after_sign_in_path_for(resource)
   #お気に入り登録(POST)の場合、after_login_to_post_pathに遷移します。
    if session[:after_login_to_post]
      after_login_to_post_path
    else
      super
    end
  end
end

 ログイン後にセッション情報からログイン直前のページ情報を復元

セッション情報から、POSTリクエストの情報を取得し、設定します。

class TopController < ApplicationController
  def after_login_to_post
   #セッションにafter_login_to_postがあれば、
    if session[:after_login_to_post]
      @back_controller = session[:after_login_to_post]['controller_name']
      @back_action = session[:after_login_to_post]['action_name']
      @params = session[:after_login_to_post]['params']
   #セッションをクリア
      session[:after_login_to_post] = nil
      render :after_login_to_post, layout: false
    else
      #直接アクセスが来たら、TOPに遷移する。
      redirect_to top_path
    end
  end
end

 真っ白VIEW

after_login_to_postのVIEWは自動サブミットします。

一瞬だけ真っ白なページが表示されますが、

自動サブミットによって、POST送信が出来ます。

after_login_to_post.slim

doctype transitional
html[xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja" dir="ltr"]
  head
    meta[http-equiv="Content-Type" content="text/html; charset=UTF-8"]
    title = '戻る'
  body onLoad="document.forms[0].submit()"
    - if @back_controller && @back_action && @params
      = form_tag( { controller: @back_controller, action: @back_action }, { method: 'post' } ) do
        = hidden_field_tag 'id', @params['id']
        <noscript>
        = button_tag '戻る', class: 'btn_sub'
        </noscript>

 routes

  ### ログイン後、POSTアクションに戻る ###
  get 'after_login_to_post', to: 'top#after_login_to_post'

 参照

http://easyramble.com/cannot-post-redirect-on-rails.html

記事を共有

最近人気な記事