Rails Devise入門ガイド(2): ログイン・ログアウト・新規登録の実装と基本ヘルパーの使い方

前回(第1回)では、DockerとTablerを使ったRails開発環境に、定番の認証GemであるDeviseをインストールし、初期設定、Userモデルの作成、そして認証関連のURL(/admin/sign_inなど)を/admin配下に設定しました。Deviseを動かすための土台はできましたが、まだユーザーが実際にログインしたり、アカウントを作成したりすることはできませんでした。

この第2回では、いよいよ実際にユーザー認証機能を「使える」状態にします!具体的には以下の内容を進めます。

  • devise_forによって生成されたルーティングを確認します。
  • ユーザーがアカウントを新規登録(サインアップ)できることを確認します。
  • 登録したアカウントでログイン(サインイン)、そしてログアウト(サインアウト)できることを確認します。
  • Deviseが提供する便利なヘルパーメソッドを使い、ログイン状態に応じて表示を変えたり、アクセス制御をしたりする方法を学びます。

この記事を読み終えれば、あなたのアプリケーションでDeviseによる基本的な認証フローが一通り動作し、その仕組みを理解できるはずです。

目次

前提となる開発環境

この記事は、以下の環境が整っていることを前提としています。

DockerおよびDocker Compose

アプリケーションとデータベースなどがコンテナ管理されている。

Tablerレイアウト

Tabler UIキット が導入済みで、app/views/layouts/admin.html.erb 等の管理画面用レイアウトがある。

Devise導入済み

第1回の内容に従い、Devise Gemがインストールされ、初期設定、Userモデル生成、DBマイグレーションが完了し、認証URLが /admin 配下に設定されている。

Flashメッセージ表示

レイアウトに <%= render "shared/flash_messages" %> が設置されている。

Step 1: Deviseルーティングの確認

まず、第1回で config/routes.rb に設定した devise_for が、実際にどのようなURLパスを生成しているか確認しましょう。Railsコンテナ内で以下のコマンドを実行します。

# devise に関連するルーティングを表示
bin/rails routes | grep devise

出力結果の中に、以下のような /admin から始まるパスが含まれているはずです(scope '/admin'path: '', path_names の設定に基づきます)。

        new_user_session GET    /admin/sign_in(.:format)        # ログインフォーム表示
            user_session POST   /admin/sign_in(.:format)        # ログイン処理
    destroy_user_session DELETE /admin/sign_out(.:format)       # ログアウト処理
           user_password POST   /admin/password(.:format)       # パスワードリセットメール送信
       new_user_password GET    /admin/password/new(.:format)   # パスワードリセット要求フォーム
      edit_user_password GET    /admin/password/edit(.:format)  # パスワード再設定フォーム
           user_password PATCH  /admin/password(.:format)       # パスワード更新処理
                         PUT    /admin/password(.:format)       # パスワード更新処理
                         POST   /admin/password(.:format)       # パスワードリセットメール送信
cancel_user_registration GET    /admin/cancel(.:format)         # サインアップキャンセル
   new_user_registration GET    /admin/sign_up(.:format)        # サインアップフォーム表示
  edit_user_registration GET    /admin/edit(.:format)           # アカウント編集フォーム表示
       user_registration PATCH  /admin(.:format)                # アカウント更新処理
                         PUT    /admin(.:format)                # アカウント更新処理
                         DELETE /admin(.:format)                # アカウント削除処理
                         POST   /admin(.:format)                # サインアップ処理

これらのパスを使って、実際に認証機能を試していきます。

Step 2: サインアップ機能の実装と確認

ユーザーが自身のアカウントを作成できるようにします。

1. 開発サーバーを起動(まだ起動していない場合)
bash docker compose up -d
2. サインアップページへアクセス
表示内容

Deviseのデフォルトのサインアップフォーム(Email, Password, Password confirmation入力欄)が表示されます。

注意

第1回の最後で触れた通り、この時点では管理画面のTablerレイアウトは適用されていません。これは、Deviseのコントローラーがデフォルトのレイアウトを使用するためです。レイアウト適用とフォームのカスタマイズは次回の記事で行います。

アカウント作成

フォームに有効なメールアドレスと、パスワード(確認用も同じもの)を入力して送信ボタンをクリックします。

結果確認

成功すればリダイレクト、失敗すればエラーメッセージが表示されます。

結果確認
成功時

デフォルトではアプリケーションのルートパス (root_path で設定したパス) にリダイレクトされ、「アカウント登録が完了しました。」(Welcome! You have signed up successfully.) のような notice Flashメッセージが表示されるはずです。

失敗時

パスワードが短い、確認用パスワードが違う、Email形式が不正などのバリデーションエラーがあれば、フォームページが再表示され、エラー内容を示す alert Flashメッセージが表示されます。(これは :validatable モジュールによるものです)

DB確認 (任意)

Railsコンソール (bin/rails c) で User.countUser.last を実行し、ユーザーがデータベースに正しく保存されたことを確認できます。

これで、ユーザー登録機能が動作することが確認できました。

Step 3: ログイン (サインイン) と ログアウト (サインアウト) を試す

次に、登録したアカウントでログインし、その後ログアウトできるかを確認します。

1. サインインページへアクセス

ブラウザで http://localhost:3000/admin/sign_in にアクセスします。デフォルトのサインインフォームが表示されます

2. ログイン試行
成功

Step 2で登録したメールアドレスとパスワードを入力し、送信します。
成功すると、デフォルトでルートパスにリダイレクトされ、「ログインしました。」(Signed in successfully.) の notice Flashメッセージが表示されます。

失敗

情報が間違っている場合、サインインページが再表示され、「メールアドレスまたはパスワードが違います。」(Invalid Email or password.) の alert Flashメッセージが表示されます。

ログイン済みの場合の挙動

もし、既にログインしている状態(例えば、サインアップ直後など)で /admin/sign_in にアクセスしようとすると、Devise は自動的にルートパスなどにリダイレクトし、“You are already signed in.” (すでにログインしています。) という alert Flashメッセージを表示します。
これはエラーではなく、Devise の正常な動作であり、二重ログインを防ぐための挙動です。
サインイン機能を試す際は、一度ログアウトしてからアクセスするか、シークレットモード/プライベートブラウジングのウィンドウで試すと良いでしょう。

3. サインアウト用リンク/ボタンの設置

ログアウト機能を使うには、ログアウト処理を行うパス (/admin/sign_out) へ DELETEメソッドでリクエストを送る必要があります。
管理画面共通ヘッダー (app/views/shared/_header.html.erb) などにリンクまたはボタンを設置します。

<header class="navbar navbar-expand-md d-print-none">
  <div class="container-xl">
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#sidebar-menu" aria-controls="sidebar-menu" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <h1 class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3">
      <%= link_to admin_root_path, class: "navbar-brand" do %>
        MyApp
      <% end %>
    </h1>

    <div class="navbar-nav flex-row order-md-last">
      <div class="nav-item">
        <%= button_to "ログアウト", destroy_user_session_path, method: :delete, class: "nav-link", form: { class: 'd-inline' } %>
      </div>
    </div>
  </div>
</header>
  • destroy_user_session_path/admin/sign_out へのルーティングヘルパーです。
  • 重要:button_tomethod: :delete を指定するか、link_todata: { turbo_method: :delete } を指定しないと、GETリクエストになってしまい正しくログアウトできません。
4. ログアウト実行

ログインした状態で、設置したログアウトリンク/ボタンをクリックします。

5. 結果確認

成功すると、デフォルトでルートパスにリダイレクトされ、「ログアウトしました。」(Signed out successfully.) の notice Flashメッセージが表示されます。

これで、ログインとログアウトの基本的なフローも動作することが確認できました。

Step 4: Deviseヘルパーで認証状態を活用する

Deviseは、ビューやコントローラーで認証状態を簡単に扱えるように、いくつかの便利なヘルパーメソッドを提供します。これらを使ってアプリケーションをより機能的にしましょう。

authenticate_user! : コントローラーでのアクセス制御

これはコントローラー内 (主に before_action として) で使用し、ログインしていないユーザーからのアクセスを拒否(ログインページへリダイレクト)するためのメソッドです。管理画面全体など、特定のエリアをログイン必須にしたい場合に非常に役立ちます。

実装例: 管理画面全体をログイン必須にする
# app/controllers/admin/base_controller.rb
class Admin::BaseController < ApplicationController
  layout 'admin'

  before_action :authenticate_user!
end

この1行を追加するだけで、/admin 配下の(Admin::BaseController を継承している)全てのページは、ログインしていないユーザーがアクセスしようとすると自動的にログインページ (/admin/sign_in) へリダイレクトされるようになります。

user_signed_in?current_user : ビューでの表示切り替えとユーザー情報表示

user_signed_in?

ユーザーが現在ログインしているかどうかを true / false で返します。ビューファイル内で条件分岐によく使われます。

current_user

現在ログインしているユーザーの User モデルオブジェクトを返します。ログインしていない場合は nil を返します。ユーザーの名前やメールアドレスなどを表示するのに使います。

実装例: 管理画面ヘッダーのナビゲーションを完成させる
<%# app/views/layouts/admin.html.erb のヘッダー部分の例 %>
<header class="navbar navbar-expand-md d-print-none">
  <div class="container-xl">
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#sidebar-menu" aria-controls="sidebar-menu" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <h1 class="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0 pe-md-3">
      <%= link_to admin_root_path, class: "navbar-brand" do %>
        MyApp
      <% end %>
    </h1>

    <div class="navbar-nav flex-row order-md-last">
      <% if user_signed_in? %>
        <%# --- ログインしている場合の表示 --- %>
        <div class="nav-item dropdown">
          <a href="#" class="nav-link d-flex lh-1 text-reset p-0" data-bs-toggle="dropdown" aria-label="Open user menu">
            <div class="d-none d-xl-block ps-2">
              <%# current_user を使ってメールアドレス表示 %>
              <div><%= current_user.email %></div>
              <div class="mt-1 small text-muted">ログイン中</div>
            </div>
          </a>
          <%# ドロップダウンメニュー %>
          <div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
            <%= link_to "アカウント設定", edit_user_registration_path, class: "dropdown-item" %> <%# /admin/account %>
            <div class="dropdown-divider"></div>
            <%= button_to "ログアウト", destroy_user_session_path, method: :delete, class: "dropdown-item" %>
          </div>
        </div>
      <% end %>
    </div>
  </div>
</header>
  • if user_signed_in? でログイン状態をチェックし、表示判定をしています。
  • ログイン中は current_user.email でメールアドレスを取得して表示しています。

これらのヘルパーを使うことで、認証状態に基づいた動的なページを簡単に構築できます。

まとめと次回予告

第2回では、Devise を使ったアプリケーションで、ユーザーが実際にサインアップ、サインイン、サインアウトできることを確認しました。また、Devise が提供する user_signed_in?, current_user, authenticate_user! といった基本的なヘルパーメソッドを使い、ビューの表示を切り替えたり、コントローラーでアクセス制御を行ったりする具体的な方法を学びました。

これで、あなたの Rails アプリケーションは動作する認証機能の基盤を持つことになりました。しかし、現状では Devise の認証画面はデフォルトのままで、管理画面のレイアウトも適用されていません。

次回(第3回) は、この認証画面の見た目を改善します。具体的には、Devise の認証画面(サインイン、サインアップ等)に管理画面の Tabler レイアウト (admin.html.erb) を適用する方法と、rails g devise:views コマンドで生成したビューファイルを編集してフォーム等の見た目を Tabler デザインにカスタマイズする手順を詳しく解説します。より洗練された認証画面を目指しましょう!

未経験からエンジニアへ転職!おすすめの転職サービスはこちら

「未経験だけどエンジニアになりたい…」「IT業界に興味があるけど、どこから始めるべきかわからない…」
そんな方におすすめなのが、プログラミングスクールを活用した転職活動です。
実績豊富なスクールを利用すれば、未経験からでもエンジニアとしての転職がぐっと近づきます!

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次