ユーザ新規登録 (実務未経験状態でLaravelを使用した共同開発　タスク2)

## 0.背景
本記事は、記事「実務未経験状態でLaravelを使用した共同開発」で取り組んだタスクのうち、ユーザ新規登録機能についてまとめたもの

https://qiita.com/ashi__mo/items/9abff3c5227660dcddba

## 1.仕様内容
・ユーザ新規登録処理の実装
・ユーザ新規登録画面の作成
・バリデーションの実装
・パスワード表示切替機能

##### UI
![user_register.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842139/a60ac5bb-cbc7-4e4f-9e2c-2db07cf92d7e.png)

## 2.タスクの見積もり
##### 期間
・１週間
##### 理由
・トレイトの技術内容に不安があった
・Jsコンパイルに関する知識が不足していた
・他メンバーのタスク（view：ヘッダー、フッター、レイアウト）のマージ待ちがあった
・PRレビュー及び修正作業の期間も見込んだ
##### 実績
・仕様作成完了　4日
・PR完了　4日
・マージ完了　6日
・PRレビュー修正回数：2回

## 3.実装内容
##### MVC + Routing 観点から
①Routing
※laravelバージョン6を使用
・web.php
``` 
Route::prefix('/register')->group(function () {
Route::get('/','Auth\RegisterController@showRegistrationForm')->name('signup');
Route::post('/','Auth\RegisterController@register')->name('signup.post');
```
・既存のRegisterControllerのトレイトを使用
・showRegistionForm：ユーザ新規登録画面表示（トレイト）
・register：ユーザ新規登録処理（トレイト）

②Model
・追加記述及び新規作成無

③Controller
・既存のRegisterControllerを使用
・laravelが提供するRegisterUsersトレイトを使用
・バリデーション部分のみオーバーライドで処理追加
```
 public function register(RegisterRequest $request)
    {
        event(new Registered($user = $this->create($request->validated())));

        $this->guard()->login($user);

        return $this->registered($request, $user)
            ?: redirect($this->redirectPath());
    }
```
④FormRequest
・RegisterRequestを作成
```
    public function rules()
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ];
    }

        public function messages()
    {
        return [
            'name.required' => '名前は必須です。',
            'name.string' => '名前は文字列で入力してください。',
            'name.max' => '名前は255文字以内で入力してください。',
            'email.required' => 'メールアドレスは必須です。',
            'email.email' => '有効なメールアドレスを入力してください。',
            'email.unique' => 'このメールアドレスは既に使用されています。',
            'password.required' => 'パスワードは必須です。',
            'password.min' => 'パスワードは8文字以上で入力してください。',
            'password.confirmed' => 'パスワードが一致しません。',
        ];
    }
```
⑤View
・register.blade.phpを作成
```
<div class="w-100 text-start mt-2">
    <label class="form-label">パスワード</label> <br>
    <div class="d-flex input-group">
        <input type="password" name="password" value="{{old('password')}}" class="form-control col-auto">
        <button type="button" class="btn btn-outline-secondary" data-toggle="password">
            <i class="bi bi-eye"></i>
        </button>
    </div>
    @error('password')
        <p class="text-danger">{{ $message }}</p>
        @enderror
</div>
```
※内容抜粋
　・パスワード、パスワード確認部分のみ閲覧切替ボタンを設置
　・エラーメッセージを各項目下に表示
⑥Js
既存のapp.jsに記載
```
document.addEventListener("DOMContentLoaded", () => {
    document.querySelectorAll("[data-toggle='password']").forEach((button) => {
        button.addEventListener("click", () => {
            const input = button.previousElementSibling;
            const icon = button.querySelector("i");

            if (!input || !icon) return;

            const isPassword = input.type === "password";
            input.type = isPassword ? "text" : "password";
            icon.classList.toggle("bi-eye");
            icon.classList.toggle("bi-eye-slash");
        });
    });
});
```
・querySelectorAllで複数のパスワード欄に対応：再利用性、工数削減
・laravelMixでビルド実施
## 4．テスト実施内容
・ユーザ登録画面の表示を確認（遷移先、元は他メンバータスク、未実装）
・ユーザ登録、usersテーブルへ追加を確認
・バリデーションの動作と、エラーメッセージ表示位置の確認（各項目下に表示）
## 5．PRレビュー
・初期：post.register → 修正後：signup.post【「主語.述語」形式がより明確でわかりやすい】
・インデントのズレ：vscodeのインデント自動生成が4ではなく2で設定になっていた。

## 6.本実装に関して
・可読性：トレイトや独自実装部分にはコメントを記載し、他メンバーでも理解しやすく工夫
・再利用性：JSによるDOM操作はquerySelectorAllで実装。他ページ（例：ログイン画面）でも流用可能な実装にした