0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[devise]ログイン後に遷移するページを指定

Posted at

解決したいこと

Railsのgemであるdeviseでユーザー管理を実装する際、
ログイン後に遷移するページを指定する方法。

結論

after_sign_in_path_forというヘルパーを利用する。
ヘルパー内で、ログイン後に遷移させたいパスを指定する。

Githubリンク
Documentリンク

実装したコード

  • deviseは導入済みで、サインアップ・サインイン・ログアウト機能は実装済
  • rails g controller usersを実行して、usersコントローラーを作成済み

config/routes.rb

Rails.application.routes.draw do
  devise_for :users
  resources :users, only: [:show] #追加したルーティング
end

app/controllers/application_controller.rb

 private
  def after_sign_in_path_for(resource)
    user_path(resource)
  end

usersコントローラーのshowアクションを呼び出すパスを設定。
privateメソッドでも問題なく動作したため、こちらに定義した。

app/controllers/users_controller.rb

class UsersController < ApplicationController
  before_action :authenticate_user!

  def show
    @user = User.find(params[:id])
  end
end

マイページ(app/views/users/show.html.erb)で、ユーザー情報を使用するため、
usersテーブルから、該当idのユーザーレコードをとってくる様に設定。
また、ログインしていないユーザーを強制的にログインページへ飛ばすため、
usersコントローラー側でauthenticate_user!を設定した。

ヘルパーの引数resourceは何か

結論:「ログインユーザーのレコード(インスタンス)」

実装コードで動作確認はできた。
しかし、「resourceには何が渡されているのか?」と気になった。

binding.pryで調べてみると
resourceには、ログインユーザーのレコードが入っていた。
paramsには、ログイン時に入力した情報が乗っていた。

    16: def after_sign_in_path_for(resource)
    17:   user_path(resource.id)
 => 18:   binding.pry
    19: end

[1] pry(#<Devise::SessionsController>)> resource
=> #<User id: 2, email: "test@test", nickname: "テスト", created_at: "~(省略)", updated_at: "~(省略)">
[2] pry(#<Devise::SessionsController>)> params
=> <ActionController::Parameters {
    "authenticity_token"=>"~(省略), 
    "user"=>{"email"=>"test@test", "password"=>"ttttt1", "remember_me"=>"0"},
   "commit"=>"Log in",
   "controller"=>"devise/sessions",
   "action"=>"create"
    } permitted: false>

ちなみにuserコントローラーのshowアクションに飛んだときのparams。
ちゃんとidが飛んでいた。


    4: def show
    5:   @user = User.find(params[:id])
 => 6:   binding.pry
    7: end

[1] pry(#<UsersController>)> params
=> <ActionController::Parameters {"controller"=>"users", "action"=>"show", "id"=>"2"} permitted: false>

ヘルパーは、誰が呼び出してるのか

結論:「sessionsコントローラーのcreateアクション」

次は、ヘルパーの呼び出しが気になった。
authenticate_user!とは異なり、
before_actionなどで、ヘルパーメソッドの呼び出しはしていない。

まずは、Gitでsessionsコントローラーのコードを見てみる。

devise/app/controllers/devise/sessions_controller.rb

  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message!(:notice, :signed_in)
    sign_in(resource_name, resource)
    yield resource if block_given?
    respond_with resource, location: after_sign_in_path_for(resource)
  end

最後行でafter_sign_in_path_forが呼び出されている。
つまり、sessionsコントローラーのcreateアクションを動かすと、
必ず呼ばれるメソッドだと解釈した。
そのため、before_actionのような呼び出しも不要だった。

感想

「ログイン後に、マイページへ遷移させたい」という機能は実装できたが、
devise側でどうなっているのか、については理解しきれなかった。

目的は達成したので、これ以上ここを掘り下げることに時間を使うべきではないが、
後々理解したいと思った。

特にRails側の機能であるrespond_with resourceとlocationオプション。
また、after_sign_in_path_forのオーバーライドと
deviseController、ApplicationControllerの関係性。
プラス、deviseコントローラーに定義されているhelper内の記述など。

0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?