本ガイドでは、Railsをはじめようで作成した練習用アプリ「store」にユーザー登録とユーザー設定機能を追加する方法について解説します。本ガイドでは、『Railsをはじめよう』の最終コードを出発点とします。
このガイドの内容:
ユーザー登録(sign up)機能は、新しいユーザーを登録する処理であり、アプリケーションに追加する最も一般的な機能の1つです。Railsをはじめようガイドで構築したeコマースアプリケーションには認証機能しかなく、ユーザーを登録するにはRailsコンソールやスクリプトで作成しなければなりません。
この機能は、他の機能を追加する前に実装しておく必要があります。たとえば、ユーザーがウィッシュリストを作成可能にするには、まずユーザーが登録できる必要があります。その後、アカウントに関連付けられたウィッシュリストを作成できます。
それでは始めましょう。
認証機能ジェネレータでユーザーを自分のアカウントにログインさせる機能は、既ににRailsをはじめようガイドで使いました。認証機能ジェネレータを用いて、Userモデルを作成し、データベースにemail_address:stringとpassword_digest:stringのカラムを追加しました。また、Userモデルにhas_secure_passwordメソッドを追加し、パスワードと確認を処理します。これにより、ユーザー登録機能をアプリケーションに追加するために必要な処理はほぼ完了します。
登録時は、ユーザーの名前も保存しておくとよいでしょう。これにより、アプリケーション内でユーザー体験をパーソナライズし、ユーザーを「XX様」のように直接名前で呼びかけることが可能になります。
それでは、データベースにfirst_nameとlast_nameのカラムを追加しましょう。
ターミナルで以下のコマンドを実行して、これらのカラムを持つマイグレーションを作成します。
$ bin/rails g migration AddNamesToUsers first_name:string last_name:string
続いてデータベースのマイグレーションを実行します。
$ bin/rails db:migrate
first_nameとlast_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メソッドは、パスワードが存在することだけをバリデーションします。セキュリティを強化するため、パスワードの最小文字数のチェックやパスワードが十分複雑かどうかのバリデーションも追加することを検討しましょう。
次に、ユーザー登録機能を追加して新しいユーザーを登録できるようにしましょう。
新しいユーザーを登録するのに必要なカラムがすべて揃ったので、次のステップではユーザー登録用のルーティングとそれに対応するコントローラを作成します。
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>