ログイン情報の取得を簡単にする
ユーザーがログインしていればsession[:user_id]にユーザーのIDが格納された状態となるのでログイン後はセッションが
生きている限り、下記のコードでユーザーを簡単に取得することができる。
User.find_by(id: session[:user_id])
このようなログインしているユーザーを取得する処理は、頻繁に必要になるので、
コントローラやビューから簡単に呼ぶのが定石になっている。
簡単な実現方法としては、ApplicationControllerにcurrent_userというような名前のメソッドを定義することで
全てのコントローラから利用できるようにします。
さらにhelper_methodを指定することで、全てのビューから使えるようにする。
class ApplicationController < ActionController::Base
helper_method :current_user
private
def current_user
@current_user ||= User.find_by(id: session[:user_id]) if session[:user_id]
end
end
これでログインに成功すればsession[:user_id]にユーザーのidが入り、current_userでUserオブジェクトを取得できる
状態になりました。
このままでは、ログインしていなくてもどの機能も利用できてしまうので、ログインする必要性に乏しい状態。
各種機能を、ログインしている時にだけ使えるようにする必要がある。
ただし、その前にログアウトから実装する。理由は一旦ログインに成功すると、ログインしていない状態を作り出すことが難しく、開発上不便だから。
ログアウト機能を実装する
ログアウト機能とは、アプリケーションの状態を、ログインしている状態からログインしていない状態に変えること。 したがって、このアプリの場合は、session[:user_id]にnilが入っている状態にすれば良いということになる。セッションからuser_idの情報だけをピンポイントで消すには以下のようにすればできる。
session.delete(:user_id)
ただし、user_idだけでなく、ユーザーに紐づくその他の情報をセッションに入れるようにしている場合には、ログアウト時にセッション内の情報を
全て削除するようにします。
reset_session
それでは、このようなログアウト処理を実行するdestroyアクションを、SessionsControllerに追加していきます。
まず、ログアウトのためのルーティングを定義していく。
delete '/logout', to: 'session#destroy'
次にアクションを追加
def destroy
reset_session
redirect_to root_url, notice: 'ログアウトしました'
end
これでアクションの準備ができた。最後にアプリケーション内に「ログアウト」のリンクを追加してみる。
doctype html
html
head
title
| Taskleaf
= csrf_meta_tags
= csp_meta_tag
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload'
body
.app-title.navbar.navbar-expand-md.navbar-light.bg-light
.navbar-brand Taskleaf
ul.navbar-nav.ml-auto
- if current_user
li.nav-item= link_to 'タスク一覧', tasks_path, class: 'nav-link'
li.nav-item= link_to 'ユーザー一覧', admin_users_path, class: 'nav-link'
li.nav-item= link_to 'ログアウト', logout_path, method: :delete, class: 'nav-link'
- else
li.nav-item= link_to 'ログイン', login_path, class: 'nav-link'
.containar
- if flash.notice.present?
.alert.alert-success= flash.notice
= yield
ここではさっき定義したcurrent_userメソッドを利用して、ログインしている時はログアウトのリンクを表示している。
また、以前に追加したユーザー管理機能へのリンクも表示している。
一方、ログインしていない時はログイン画面へのリンクを表示します。
これでログインとログアウトを行うことができるようになったがあまり仕上がっているとは言えない。
認証機能を追加する場合は「ログインしていなければ一定の機能を使えなくする」「ログインしているユーザーが自分のデータしか見られなくする」
と、いった制限も付け加えたいところです。
次回でやっていきたいと思います。
参考書籍: 現場で使える Ruby on Rails5 速習実践ガイド