ログアウトの実装
Sessionsコントローラーのdestroyアクションに以下の実装を追加します。
…(中略)…
def destroy
reset_session
redirect_to login_url
end
…(中略)…
reset_sessionメソッドでセッションを初期化後、ログイン画面にリダイレクトしています。
これでログアウトができるようになりましたが、現状ではログアウトする遷移元のリンクが存在しません。それをユーザー詳細画面に追加してみましょう。
…(中略)… <%= link_to 'Edit', edit_user_path(@user) %> | <%= link_to 'User list', users_path %> <% if logged_in? %> <%= link_to 'Logout', logout_path, method: :delete %> <% end %>
users_pathのリンク先の文言をBackからUser listに変更しています。その後の行でlogged_in?メソッドでログイン可否を判定し、真ならログアウトのリンクを出力しています。
logged_in?メソッドはまだ定義していないので、定義しましょう。定義先ですが、ログイン判定はコントローラーやビューなど、さまざまなところから呼ぶ可能性があるため、ヘルパーメソッドとして定義します。
module SessionsHelper
def current_user
@current_user ||= User.find_by(id: session[:user_id])
end
def logged_in?
current_user.present?
end
end
logged_in?メソッドはcurrent_userが存在するか、ということについてpresent?メソッドで確認しています。current_userはその上に定義したメソッドです。current_userメソッドでは、Userモデルをセッションに格納されたuser_idで検索しています。「||=」という書き方は見慣れないかもしれませんが、Rubyで初期値を変数に代入するのによく使われる記述です。@current_userがnilならUser.find_byが実行され、既にデータが格納されていればそのまま@current_userを返却します。なお、@current_userをインスタンス変数にすることで、同一セッション内で使い回すことができるようになります。
さて、@current_userを定義したのでdestroyメソッドを修正する必要があります。ログアウト後に@current_userをnilに初期化します。また、ログイン/ログアウトの処理も複数の箇所から呼ばれる可能性があるため、これを機にヘルパーメソッドに移管しましょう。
…(中略)…
def log_in(user)
reset_session
session[:user_id] = user.id
end
def log_out
reset_session
@current_user = nil
end
…(中略)…
Sessionsコントローラーのcreateおよびdestroyメソッドを、ヘルパーのlog_in/log_outメソッドを使って書き換えます。
…(中略)…
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
…(中略)…
def destroy
log_out
redirect_to login_url
end
…(中略)…
Sessionsヘルパーメソッドを全てのコントローラーから呼び出せるようにします。
class ApplicationController < ActionController::Base protect_from_forgery with: :exception include SessionsHelper end
これでログイン後にユーザー詳細からログアウトが可能となりました。早速、ログイン後のユーザー詳細からログアウトできることを確かめてみましょう。
ログイン後のユーザー詳細にログアウトリンクが出力されるようになったことが確認できます。「Logout」リンクをクリックしましょう。
ログイン画面に遷移し、ログアウトを完了していることが確認できます。
まとめ
今回はユーザー登録時にパスワードを登録できるようにし、ログイン/ログアウトフォームを開発しました。
次回はRailsが提供するフロントエンド環境を解説します。
