noggy’s blog

自分用の備忘録です。。。

8.3 ログアウト

ここでは、ログアウト機能を追加する

ログアウト用リンクは既に作成済みなので、ユーザーセッションを破棄するための有効なアクションをコントローラで作成するだけで済む。これまでSessionsコントローラのアクションはRESTfulルールに従っていた。newでログインページを表示し、createでログインを完了、といった具合。

セッションを破棄するdestroyアクションも、同じ要領で作成する。ただし、ログインの場合とは異なり、ログアウト処理は1ヶ所で行えるので、destroyアクションに直接ログアウト処理をかくことにする。具体的には、log_inメソッドの実行結果を取り消す。つまり、セッションからユーザーIDを削除する。

session.delete(:user_id) ←①

①:sessionはハッシュのようであった。ハッシュにおいて、引数に指定したキーに対応する値をハッシュ自身から取り除くには、例えば

h = {"japan" => "yen", "US" => "dollar"}
h.delete("japan")

とすればよい。これと同じ考え方。

app/helpers/sessions_helper.rb

  # 渡されたユーザーでログインする
  def log_in(user)
    session[:user_id] = user.id
  end

  # 現在の ユーザーをログアウトする
  def log_out ←追加
    session.delete(:user_id)                                                   
    @current_user = nil                
  end

ここで定義したlog_outメソッドは、Sessionsコントローラのdestroyアクションでも同様に使う。
controllers/sessions_controller.rb

  def destroy 
    log_out                                                                     
    redirect_to root_url                                                        
  end
ユーザーログアウトのテスト

test/integration/users_login_test.rb

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

①:ユーザーがログアウトして、ログアウトリンクが消えたらtrue
②:テストユーザーがログイン中でなければ(つまりログアウトなら)true
③:homeにリダイレクトされていればtrue
④:リダイレクト先(root_url)が正しいかチェック
⑤:login_path(/login)がhref=/loginというコードで存在していればtrue
⑥:href="/logout"が存在しなければ(0なら)true