Help us understand the problem. What is going on with this article?

ログインしてないときにアクセスした画面に戻りたい、GET以外でも。

More than 5 years have passed since last update.

deviseの話です。

routes.rbにはこんなかんじの定義があるとします。

confg/routes.rb
devise :users
resources :events do
  resource :attendances, only: [:create, :destroy] # 参加処理
end

例えば、/events/new にアクセスするにはuserの認証が必要。そんな時はコントローラーに以下のように書きますよね。

app/controllers/events_controller.rb
class EventsController < ApplicationController
  before_action :authenticate_user!, only: [:new] # rails3 以下なら before_filter
  def show
     # イベント表示処理
  end

  def new
    # イベント作成準備処理
  end
end

この時、ログインしてない状態で、/events/new に アクセスすると、ログインしていないのでnew_user_session_path にリダイレクトされますね。
んで、ログインした跡は、/events/new に戻ってこれる。よい。deviseよい。

今度は、イベント参加時にuserの認証が必要。そんな時は以下。

app/controllers/attendances_controller.rb
class AttendancesController < ApplicationController
  before_action :set_event
  before_action :authenticate_user! # rails3 以下なら before_filter

  def create
    # イベント参加処理
  end

  def destroy
    # イベント参加キャンセル処理
  end

  private
  def set_event
    @event = Event.find(params[:event_id])
  end
end

/events/:idviewに、こんなボタンが置いてあるイメージです。

app/views/show.html.haml
= link_to(event_attendances_path(@event), method: :post, class: 'btn') do
  = t('nav.attendaces.create')

この時、ログインしてない状態でこの参加ボタンをクリックすると、/events/:id/attendancesPOST するわけですが、ログインしていないのでnew_user_session_path にリダイレクトされますね。

んで、ログインすると、root_path に戻ってしまうのがだるい。おれの参加したかったイベントよ、、、どこへ。本当なら、/events/:id に戻りたいですよねーということで、そんな時どうするか。(前置きの長さよ)

磯野〜ソース読もうぜ〜

deviseのソースを読みましょう。

https://github.com/plataformatec/devise/blob/10c9a492ab27f48d66f50df7f1e7f5e8c68f2b0f/lib/devise/failure_app.rb#L183

session["#{scope}_return_to"] = attempted_path if request.get? && !http_auth?

なるほどね、っと。session[:user_return_to] に、/events/:id を入れておけばうまくいきそうです。

イベント参加ボタンクリック後に、イベントページに戻る

参加処理のbefore_actionsession[:user_return_to] に、/events/:id を入れる処理をかきます。

app/controllers/attendances_controller.rb
class AttendancesController < ApplicationController
  before_action :set_event
  before_action :store_event_url # 追加!
  before_action :authenticate_user! # rails3 以下なら before_filter

  def create
    # イベント参加処理
  end

  def destroy
    # イベント参加キャンセル処理
  end

  private
  def set_event
    @event = Event.find(params[:event_id])
  end

  # 追加!
  def store_event_url
    session[:user_return_to] = event_path(@event) unless user_signed_in?
  end
end

はい。こんな感じです。deviseの使っているsessionの中身を書き換えるのは怖いよ〜という方は好きにして下さい。

ppworks
最近は主にrailsです!
http://ppworks.jp
esaLLC
esa.io や pplog.net などのWebサービスを開発・デザイン・運営しています
https://team.esa.io
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away