SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

サンプルコードで学ぶRuby on Rails 5実践入門

Rails 5でログインフォームを実装する

サンプルコードで学ぶRuby on Rails 5実践入門 第5回

ログアウトの実装

 Sessionsコントローラーのdestroyアクションに以下の実装を追加します。

リスト10 app/controllers/sessions_controller.rb
…(中略)…
  def destroy
    reset_session
    redirect_to login_url
  end
…(中略)…

 reset_sessionメソッドでセッションを初期化後、ログイン画面にリダイレクトしています。

 これでログアウトができるようになりましたが、現状ではログアウトする遷移元のリンクが存在しません。それをユーザー詳細画面に追加してみましょう。

リスト11 app/views/users/show.html.erb
…(中略)…
<%= 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?メソッドはまだ定義していないので、定義しましょう。定義先ですが、ログイン判定はコントローラーやビューなど、さまざまなところから呼ぶ可能性があるため、ヘルパーメソッドとして定義します。

リスト12 app/helpers/sessions_helper.rb
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に初期化します。また、ログイン/ログアウトの処理も複数の箇所から呼ばれる可能性があるため、これを機にヘルパーメソッドに移管しましょう。

リスト13 app/helpers/sessions_helper.rb
…(中略)…
  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メソッドを使って書き換えます。

リスト14 app/controllers/sessions_controller.rb
…(中略)…
  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ヘルパーメソッドを全てのコントローラーから呼び出せるようにします。

リスト15 app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper
end

 これでログイン後にユーザー詳細からログアウトが可能となりました。早速、ログイン後のユーザー詳細からログアウトできることを確かめてみましょう。

図4 http://localhost:3000/users/1
図4 http://localhost:3000/users/1

 ログイン後のユーザー詳細にログアウトリンクが出力されるようになったことが確認できます。「Logout」リンクをクリックしましょう。

図5 http://localhost:3000/login
図5 http://localhost:3000/login

 ログイン画面に遷移し、ログアウトを完了していることが確認できます。

まとめ

 今回はユーザー登録時にパスワードを登録できるようにし、ログイン/ログアウトフォームを開発しました。

 次回はRailsが提供するフロントエンド環境を解説します。

参考文献

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
サンプルコードで学ぶRuby on Rails 5実践入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 竹馬 力(チクバ ツトム)

WINGSプロジェクト について> 有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 ...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10014 2017/03/17 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー