こんにちは!
スマレジ・テックファームのWebエンジニアやまてと申します。
はじめに
今回は、Web業界実務未経験での転職活動用にポートフォリオとして作成した『はじめてのWebアプリ開発を振り返る』記事です。
※ 作成したポートフォリオは、絵本を読み聞かせしたことの記録・管理を、家族と共有できるWebアプリケーションです
実装したオリジナルの機能の一つである「家族ユーザー招待」機能について、記事にします。
概要と基本設計
詳細設計と実装
(1) 家族招待メール送信フォームの作成
(5) ユーザー登録フォームと登録処理の作成【今回】
今回は、家族招待用の新規登録フォーム画面表示処理、家族ユーザー登録処理の作成手順です。
目次
- はじめに
- 1. ルーティングの確認
- 2. 「家族招待用の登録フォーム画面表示」処理の追加
- 3. 家族招待用の登録フォーム画面の作成
- 4. 「家族ユーザー登録」処理の追加
- 5. 家族招待用の登録フォーム画面の確認
- おわりに
使用技術、サービスなど
- フロントエンド
- HTML 5 / CSS 3
- Bootstrap 4.5.0
- JavaScript
- Vue.js 2.6.11
- jQuery 3.5.1
- HTML 5 / CSS 3
- バックエンド
- メール関連
- MailHog(開発者向けのメールテストツール、開発環境)
- SendGrid(メール配信サービス、本番環境)
1. ルーティングの確認
ルーティングの追加は、以下のステップで完了しています。
2. 「家族招待用の登録フォーム画面表示」処理の追加
app/Http/Controllers/Auth ディレクトリの RegisterController.php に showInvitedUserRegistrationForm
メソッドを追加します。
- 編集:backend/app/Http/Controllers/Auth/RegisterController.php
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Providers\RouteServiceProvider; use App\User; use App\Family; use App\Child; use App\Invite; // 追加 use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; use Laravel\Socialite\Facades\Socialite; use Illuminate\Support\Str; use Illuminate\Validation\Rule; class RegisterController extends Controller { // 省略 // 「家族招待用の登録フォーム画面表示」処理の追加 public function showInvitedUserRegistrationForm(string $token) { $invite = Invite::where('token', $token)->first(); if (!isset($invite)) { abort(401); } return view('auth.invite_register', [ 'token' => $invite->token, 'family_id' => $invite->family_id, 'email' => $invite->email, ]); } // 省略 }
use App\Invite;
を追加して、トークンを管理している Invite モデルからデータを取得できるようにしておきます。- トークンが Invite モデルにない場合は、 401 エラーを返すようにしました。
3. 家族招待用の登録フォーム画面の作成
家族招待用の登録フォーム画面の blade を作成します。以下の画面の作成です。
- 作成・編集:backend/resources/views/auth/invite_register.blade.php
@extends('app') @section('title', '招待ユーザー登録-よんで-') @section('content') @include('auth.nav') <div class="bg-paper py-4"> <div class="container" style="max-width: 540px"> <h3 class="text-center"> よんで の新規登録(家族招待用) </h3> <h4 class="text-center"> <b>ようこそ、 よんで へ。</b> </h4> <div class="card my-4 shadow-sm"> <div class="card-body"> @include('error_card_list') <form method="POST" action="{{ route('register.invited') }}"> @csrf <input type="hidden" name="token" value="{{ $token }}"> <input type="hidden" name="family_id" value="{{ $family_id }}"> <input type="hidden" name="email" value="{{ $email }}"> <p class="x-small"> (<span class="text-danger">*</span>は必須項目です) </p> <div class="form-group"> <label for="email">メールアドレス</label> <input class="form-control" type="text" id="email" name="email" value="{{ $email }}" disabled required> </div> <div class="form-group"> <label for="nickname">ユーザーネーム</label><span class="text-danger">*</span> <input class="form-control" type="text" id="nickname" name="nickname" placeholder="ユーザーネームを入力" required value="{{ old('nickname') }}"> <p class="text-muted small ml-1">50文字以内</p> </div> <div class="form-group"> <label for="password">パスワード</label><span class="text-danger">*</span> <input class="form-control" type="password" placeholder="パスワードを作成" id="password" name="password" required> <p class="text-muted small ml-1">半角英数・記号:8文字以上</p> </div> <div class="form-group"> <label for="password_confirmation">パスワード(確認)</label><span class="text-danger">*</span> <input class="form-control" type="password" placeholder="パスワードを確認" id="password_confirmation" name="password_confirmation" required> </div> <label for="agree" class="small" role="button"> <span class="d-flex flex-wrap"> <span> <input type="checkbox" id="agree" required> <a href="{{ route('privacy') }}" class="text-teal1 ml-2" target="_blank" title="プライバシーポリシーをブラウザの別画面で開く">プライバシーポリシー</a> <span>を確認し、</span> </span> <span>同意</span> <span> <span> <span>しました。</span><span class="text-danger">*</span> </span> </span> </label> <button type="submit" class="btn btn-block bg-pink text-decoration-none text-white mt-4"> <b>登録</b> </button> </form> </div> </div> </div> </div> @include('footer') @endsection
4. 「家族ユーザー登録」処理の追加
app/Http/Controllers/Auth ディレクトリの RegisterController.php に registerInvitedUser
メソッドを追加します。
- 編集:backend/app/Http/Controllers/Auth/RegisterController.php
<?php // 省略 class RegisterController extends Controller { // 省略 // 「家族招待用のユーザー登録」処理 public function registerInvitedUser(Request $request) { if (!$invite = Invite::where('token', $request->token)->first()) { abort(401); } $request->validate([ 'nickname' => ['required', 'string', 'max:50'], 'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users', 'email')->whereNull('deleted_at'),], 'password' => ['required', 'string', 'min:8', 'confirmed'], ]); $checkUniqueName = true; while ($checkUniqueName) { $userName = Str::random(16); $checkUniqueName = User::where('name', $userName)->exists(); } $user = User::create([ 'name' => $userName, 'nickname' => $request->nickname, 'email' => $request->email, 'email_verified_at' => now(), 'password' => Hash::make($request->password), 'family_id' => $request->family_id, ]); $this->guard()->login($user, true); $invite->delete(); return $this->registered($request, $user) ?: redirect($this->redirectPath()); } // 省略 }
- 一連の流れを通して、招待する側と同一の
family_id
にしてユーザー登録することで、登録後、家族ユーザーとして本棚を共有できるようにしています。 $invite->delete();
で招待用トークンは削除して、使えないようにしています。
5. 家族招待用の登録フォーム画面の確認
前回ブラウザで確認した MailHog の受信ボックスに届いているメールのリンクをクリックすると、フォーム画面が表示されるようになっていることを確認します。
入力して登録ボタンを押すと、招待する側と同一の family_id
で登録されました。
登録後のプロフィール設定画面、家族設定画面は、以下の通りです。
phpMyAdmin での users テーブルのデータの確認画面です。
最後の行の id 5 が追加されたデータです。
おわりに
実装したオリジナルの機能の一つである「家族ユーザー招待」機能についてはこれで完結です。記事にする過程で、1年ほど触っていない Laravel の実装について、思い出すことができたので良い復習の機会になりました。理解の不足についても少し穴埋めできたと感じています。
ありがとうございました。
これまでの関連記事
これまでの関連記事です。
100いいね、100ありがとうございます!4カ月で4記事が100いいね以上いただいてました!...ありがたい🙏🙏🙏🙏 https://t.co/qFhRyrIFuq
— やまて|Webエンジニア2年目 (@r_yamate) 2022年11月4日
スマレジ入社時研修当時のレビューを出しにして、たくさんのいいねを獲得しました。