概要
ユーザー認証によってサインインしたユーザーの情報を保持し、サインアウト時にそれを破棄する。
- サイトのルートはトップページ
- サインインしていなければサインインページへリダイレクト
- サインイン中のユーザーの名前表示
- メニューからサインアウト可能
- サインインページ
- サインイン成功後にトップページに遷移
- サインアップページ
- サインアップ成功後にトップページに遷移
ヘルパーの追加
ヘルパーモジュールのインクルード
以降、ユーザーセッションの管理に関するメソッドをUserHelperモジュールに書いていく。
プロジェクト内でそれらを共有するため、applicationコントローラーでモジュールをインクルードする。
app/controllers/application_controller.rb
1 2 3 4 5 |
class ApplicationController < ActionController::Base protect_from_forgery with: :exception # ユーザーセッションの管理に関するメソッドモジュールをインクルード include UsersHelper end |
ヘルパーモジュールのメソッド定義
ユーザーのサインイン/サインアウト処理、サインイン中のユーザーを取得するメソッドを、UserHelper
モジュールに書く。
セッション中のユーザーをインスタンス変数に保持する。
app/helpers/user_helper.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
module UsersHelper # ユーザーIDをセットしてセッション開始(サインイン) def user_session_start(user) session[:user_id] = user.id end # セッション中のユーザーインスタンスを取得 def user_in_session # 初めて取得する場合、インスタンス変数に保存 if @user_in_session.nil? @user_in_session = User.find_by(id: session[:user_id]) # 既に取得済みなら、インスタンス変数で返す else @user_in_session end end # セッション終了(サインアウト) def user_session_end session.delete(:user_id) @user_in_session = nil end end |
サインイン・サインアウト処理
サインイン処理
サインインに成功した場合、セッションを開始してユーザIDを登録する。
app/controllers/users_controller.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
class UsersController < ApplicationController ..... def sign_in_process # フォームに値を残すため、入力内容をセットしたモデルインスタンス使う @user = User.new(user_params) # パスワードをサインアップ時と同じ方法で暗号化 encrypted_password = User.generate_digest(user_params[:password]) # アドレスとパスワードが一致する最初のユーザーを取得 user = User.find_by(email: user_params[:email], password: encrypted_password) # サインイン成功の場合、トップページに遷移 if user user_session_start(user) redirect_to top_path and return # サインイン失敗の場合、サインインページに戻る else flash.now[:danger] = "サインインできません" render :sign_in, layout: 'application_signed_out' and return end end ..... end |
サインアップ後の処理
サインアップが成功した場合も、サインイン状態と同様にセッション登録してトップページに遷移する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class UsersController < ApplicationController ..... def sign_up_process # フォームに値を残すため@userを使う @user = User.new(user_params) # 適正にユーザー登録した場合、セッションを開始しトップページに遷移 if @user.save user_session_start(@user) flash.now[:success] = "ユーザー登録しました" redirect_to top_path and return # 不適正な入力の場合、エラーを表示してサインアップページに戻る else flash.now[:danger] = @user.errors.messages.values.flatten.join("<br>") render :sign_up, layout: 'application_signed_out' and return end end ..... end |
サインアウト処理の追加
サインイン中のユーザーがサインアウトを要求した時のアクションを、usersコントローラーに定義する。
サインアウトにあたってセッションを停止し、サインインページに遷移する。
1 2 3 4 5 6 7 8 9 10 11 12 |
class UsersController < ApplicationController ..... def sign_out user_session_end redirect_to :sign_in and return end ..... end |
ルーティングの設定
サインアウトのルーティングを追加する。
1 2 3 4 5 6 7 8 9 10 |
Rails.application.routes.draw do get '/top', to: 'pages#top' get '/sign_up', to: 'users#sign_up' get '/sign_in', to: 'users#sign_in' get '/sign_out', to: 'users#sign_out' post 'sign_up', to: 'users#sign_up_process', as: :sign_up_process post 'sign_in', to: 'users#sign_in_process', as: :sign_in_process end |
ビューの修正・サインアウト
ヘッダー部にサインイン中のユーザー名を表示する。
また、ヘッダーメニューのサインアウトのリンク先をsign_outアクションとする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!DOCTYPE html> <html> ..... <body> <header> <div class="header_logo"></div> <h1>EX-BBS</h1> <p><%= user_in_session.name %>さん</p> <ul class="header_menu"> <li><%= link_to("投稿する", "#") %></li> <li><%= link_to("プロフィール", "#") %></li> <li><%= link_to("サインアウト", sign_out_path) %></li> </ul> </header> <%= yield %> </body> </html> |