3
0

More than 3 years have passed since last update.

ログイン情報の取得を簡単にする

ユーザーがログインしていればsession[:user_id]にユーザーのIDが格納された状態となるのでログイン後はセッションが
生きている限り、下記のコードでユーザーを簡単に取得することができる。


User.find_by(id: session[:user_id])

このようなログインしているユーザーを取得する処理は、頻繁に必要になるので、
コントローラやビューから簡単に呼ぶのが定石になっている。
簡単な実現方法としては、ApplicationControllerにcurrent_userというような名前のメソッドを定義することで
全てのコントローラから利用できるようにします。
さらにhelper_methodを指定することで、全てのビューから使えるようにする。

app/controllers/application_controller.rb

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に追加していきます。
まず、ログアウトのためのルーティングを定義していく。

config/rotes.rb
delete '/logout', to: 'session#destroy'

次にアクションを追加

app/controllers/sessions_controller.rb
  def destroy
    reset_session
    redirect_to root_url, notice: 'ログアウトしました'
  end

これでアクションの準備ができた。最後にアプリケーション内に「ログアウト」のリンクを追加してみる。

app/views/layouts/application.html.slim
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 速習実践ガイド

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