5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Laravel6】ユーザー招待機能の詳細設計と実装(5)ユーザー登録フォームと登録処理

Last updated at Posted at 2022-12-22

はじめに

ユーザー招待機能の詳細設計と実装(5) ユーザー登録フォームと登録処理 について投稿します。

Web業界実務未経験での転職活動用にポートフォリオとしてはじめて作成したWebアプリ開発のオリジナルの機能として 家族ユーザー招待機能 を実装したときのものです。

※ 作成したポートフォリオは、絵本を読み聞かせしたことの記録・管理を、家族と共有できるWebアプリケーションです(作成期間は、2021年2月末〜7月)

投稿内容(全5回)

本連載は以下の順番で投稿します。

今回は、ユーザー招待機能の詳細設計と実装(5) ユーザー登録フォームと登録処理 についてです。

目次

以下、本記事の目次です。

  1. ルーティングの確認
  2. 「家族招待用の登録フォーム表示」処理の追加
  3. 家族招待用の登録フォームの作成
  4. 「家族ユーザー登録」処理の追加
  5. 家族招待用の登録フォームの確認

使用技術、サービスなど

  • PHP 7.4.13
  • Laravel 6.20.20
  • MySQL 8.0.23
  • MailHog(開発者向けのメールテストツール、開発環境)

1. ルーティングの確認

ルーティングの追加は、以下のステップで完了しています。

2. 「家族招待用の登録フォーム表示」処理の追加

app/Http/Controllers/Auth ディレクトリの RegisterController.phpshowInvitedUserRegistrationForm メソッドを追加します。

編集: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 エラーを返すようにしました。

image.png

3. 家族招待用の登録フォームの作成

家族招待用の登録フォームの blade を作成します。以下の画面の作成です。

image.png

作成・編集: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.phpregisterInvitedUser メソッドを追加します。

編集: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 の受信ボックスに届いているメールのリンクをクリックすると、フォームが表示されるようになっていることを確認します。

image.png

入力して登録ボタンを押すと、招待する側と同一の family_id で登録されました。

登録後のプロフィール設定画面、家族設定画面は、以下の通りです。

  • プロフィール設定画面
    image.png

  • 家族設定画面
    image.png

phpMyAdmin での users テーブルのデータの確認画面です。

image.png

最後の行の id 5 が追加されたデータです。

おわりに

実装したオリジナルの機能の一つである「家族ユーザー招待」機能についてはこれで完結です。

記事にまとめる目的は、類似の機能を作る方への参考にしていただきたいため、自身の学習の振り返りのため、としていましたが、記事にする過程で、1年ほど触っていない Laravel の実装について、思い出すことができたので良い復習の機会になりました。

また、類似の機能を作る方への参考になると嬉しいです。

ありがとうございました。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?