演習: ユーザー登録・設定機能の追加

本ガイドでは、Railsをはじめようで作成した練習用アプリ「store」にユーザー登録とユーザー設定機能を追加する方法について解説します。本ガイドでは、『Railsをはじめよう』の最終コードを出発点とします。

このガイドの内容:

  • ユーザーのアカウント登録機能を追加
  • コントローラーアクションのレート制限
  • ネステッドレイアウトの作成
  • ロール(ユーザーと管理者)ごとにコントローラを分ける
  • ロールの異なるユーザーに対するテストの作成

目次

  1. はじめに
  2. ユーザー登録機能を追加する
  3. パスワードの編集機能
  4. ユーザープロファイルを編集する
  5. アカウントを削除する
  6. メールアドレスの更新機能を追加する
  7. 管理者とユーザーを分離する
  8. すべてのユーザーを表示する
  9. Productsコントローラを分離する
  10. テストを追加する
  11. production環境にデプロイする
  12. 今後の機能
  13. 関連リンク

1 はじめに

ユーザー登録(sign up)機能は、新しいユーザーを登録する処理であり、アプリケーションに追加する最も一般的な機能の1つです。Railsをはじめようガイドで構築したeコマースアプリケーションには認証機能しかなく、ユーザーを登録するにはRailsコンソールやスクリプトで作成しなければなりません。

この機能は、他の機能を追加する前に実装しておく必要があります。たとえば、ユーザーがウィッシュリストを作成可能にするには、まずユーザーが登録できる必要があります。その後、アカウントに関連付けられたウィッシュリストを作成できます。

それでは始めましょう。

2 ユーザー登録機能を追加する

認証機能ジェネレータでユーザーを自分のアカウントにログインさせる機能は、既ににRailsをはじめようガイドで使いました。認証機能ジェネレータを用いて、Userモデルを作成し、データベースにemail_address:stringpassword_digest:stringのカラムを追加しました。また、Userモデルにhas_secure_passwordメソッドを追加し、パスワードと確認を処理します。これにより、ユーザー登録機能をアプリケーションに追加するために必要な処理はほぼ完了します。

2.1 ユーザーに名前を追加する

登録時は、ユーザーの名前も保存しておくとよいでしょう。これにより、アプリケーション内でユーザー体験をパーソナライズし、ユーザーを「XX様」のように直接名前で呼びかけることが可能になります。

それでは、データベースにfirst_namelast_nameのカラムを追加しましょう。

ターミナルで以下のコマンドを実行して、これらのカラムを持つマイグレーションを作成します。

$ bin/rails g migration AddNamesToUsers first_name:string last_name:string

続いてデータベースのマイグレーションを実行します。

$ bin/rails db:migrate

first_namelast_nameをつなげるメソッドも追加して、ユーザーのフルネームを表示できるようにしておきましょう。

app/models/user.rbファイルを開いて、以下を追加します。

class User < ApplicationRecord
  has_secure_password
  has_many :sessions, dependent: :destroy

  normalizes :email_address, with: ->(e) { e.strip.downcase }

  validates :first_name, :last_name, presence: true

  def full_name
    "#{first_name} #{last_name}"
  end
end

has_secure_passwordメソッドは、パスワードが存在することだけをバリデーションします。セキュリティを強化するため、パスワードの最小文字数のチェックやパスワードが十分複雑かどうかのバリデーションも追加することを検討しましょう。

次に、ユーザー登録機能を追加して新しいユーザーを登録できるようにしましょう。

2.2 ユーザー登録用のルーティングとコントローラ

新しいユーザーを登録するのに必要なカラムがすべて揃ったので、次のステップではユーザー登録用のルーティングとそれに対応するコントローラを作成します。

config/routes.rbにユーザー登録用のリソースを追加します。

resource :session
resources :passwords, param: :token
resource :sign_up

ここでは、/sign_upに対する単一のルーティングを作成するために、単数形のresourceを使っています。

このルーティングは、リクエストをapp/controllers/sign_ups_controller.rbに送信します。次は、そのルーティングに対応するコントローラファイルを作成しましょう。

class SignUpsController < ApplicationController
  def show
    @user = User.new
  end
end

Userの新しいインスタンスを作成するために、showアクションを使っています。これはユーザー登録フォームを表示するアクションです。

次に、フォームを作成しましょう。app/views/sign_ups/show.html.erbを作成し、以下のコードを追加します。

<h1>Sign Up</h1>

<%= form_with model: @user, url: sign_up_path do |form| %>
  <% if form.object.errors.any? %>
    <div>Error: <%= form.object.errors.full_messages.first %></div>
  <% end %>

  <div>
    <%= form.label :first_name %>
    <%= form.text_field :first_name, required: true, autofocus: true, autocomplete: "given-name" %>
  </div>

  <div>
    <%= form.label :last_name %>
    <%= form.text_field :last_name, required: true, autocomplete: "family-name" %>
  </div>

  <div>
    <%= form.label :email_address %>
    <%= form.email_field :email_address, required: true, autocomplete: "email" %>
  </div>

  <div>
    <%= form.label :password %>
    <%= form.password_field :password, required: true, autocomplete: "new-password" %>
  </div>

  <div>