LoginSignup
0
0

More than 3 years have passed since last update.

8.3ログアウト

Posted at

ユーザーが明示的にログアウトするまではログイン状態を保てなくてはならない

ログアウトリンクはあるのでユーザーセッションを破棄するための有効なアクションをコントローラで作成するだけで済む

ログアウトの処理では、log_inメソッドの実行結果を取り消す
→セッションからユーザーIDを削除、deleteメソッドを実行

session.delete(:user_id)

上のコードで、現在のユーザーをnilに設定できる

log_outメソッド

app/helpers/sessions_helper.rb
module SessionsHelper

  # 渡されたユーザーでログインする
  def log_in(user)
    session[:user_id] = user.id
  end
  .
  .
  .
  # 現在のユーザーをログアウトする
  def log_out
    session.delete(:user_id)
    @current_user = nil
  end
end

log_outメソッドは、Sessionsコントローラのdestroyアクションでも同様に使う
セッションを破棄する(ユーザーのログアウト)

app/controllers/sessions_controller.rb
class SessionsController < ApplicationController

  def new
  end

  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      redirect_to user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
    log_out
    redirect_to root_url
  end
end

ログイン後、
deleteメソッドでDELETEリクエストをログアウト用パスに発行し、
ユーザーがログアウトして
ルートURLにリダイレクトされたことを確認します。
ログイン用リンクが再度表示されること、
ログアウト用リンクとプロフィール用リンクが非表示になることを確認

そのテスト
ユーザーログアウトのテスト(無効なログインテストも1箇所改良

test/integration/users_login_test.rb
require 'test_helper'

class UsersLoginTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
  end

  test "login with valid email/invalid password" do
    get login_path
    assert_template 'sessions/new'
    post login_path, params: { session: { email:    @user.email,
                                          password: "invalid" } }
    assert_not is_logged_in?
    assert_template 'sessions/new'
    assert_not flash.empty?
    get root_path
    assert flash.empty?
  end

  test "login with valid information followed by logout" do
    get login_path
    post login_path, params: { session: { email:    @user.email,
                                          password: 'password' } }
    assert is_logged_in?
    assert_redirected_to @user
    follow_redirect!
    assert_template 'users/show'
    assert_select "a[href=?]", login_path, count: 0
    assert_select "a[href=?]", logout_path
    assert_select "a[href=?]", user_path(@user)
    delete logout_path
    assert_not is_logged_in?
    assert_redirected_to root_url
    follow_redirect!
    assert_select "a[href=?]", login_path
    assert_select "a[href=?]", logout_path,      count: 0
    assert_select "a[href=?]", user_path(@user), count: 0
  end
end

まとめ

・Railsのsessionメソッドを使うと、あるページから別のページに移動するときの状態を保持できる。
・一時的な状態の保存にはcookiesも使える
・ログインフォームでは、ユーザーがログインするための新しいセッションが作成できる
・flash.nowメソッドを使うと、描画済みのページにもフラッシュメッセージを表示できる
・テスト駆動開発は、回帰バグを防ぐときに便利
・sessionメソッドを使うと、ユーザーIDなどをブラウザに一時的に保存できる
・ログインの状態に応じて、ページ内で表示するリンクを切り替えることができる
・統合テストでは、ルーティング、データベースの更新、レイアウトの変更が正しく行われているかを確認できる

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