LoginSignup
57
56

More than 5 years have passed since last update.

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

Last updated at Posted at 2013-07-24

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のソースを読みましょう。

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の中身を書き換えるのは怖いよ〜という方は好きにして下さい。

57
56
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
57
56