1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ポートフォリオ作成時メモ part5 ~ユーザー登録画面の編集①~

Last updated at Posted at 2024-11-18

はじめに

こんにちは、未経験からエンジニア転職を目指しているものです。
オンラインスクールで本格的に学習して6ヶ月目に入りました。PHP,Laravelを学習しポートフォリオを作成中です。ポートフォリオ作成手順及び、エラー内容を中心に記録していこうと思います。今回はユーザー登録画面の編集を行いました。本投稿は流れのメモが重点になっておりますので、削除した部分や追加した部分の詳細は割愛致します。

デフォルトの状態

Breezeインストール後のデフォルトの状態
rejister_default.png

編集後の画面

register_改善中2.png

エラーが発生

  • 添付のエラーが発生
    エラー3.png
  • エラー内容から原因を推測
    推測原因①:genderの値が正しくサーバー側に渡されていない?
    ⇨性別を登録する部分を追加していたが、どこかのディレクトリで記述が漏れていた可能性あり
    推測原因②:ジェンダーフィールドの値が適切にバリデーションや保存処理がされていない

調査内容

コントローラーでgenderフィールドがリクエストに含まれているか確認。

  • RegisteredUserController.phpのstoreメソッドで以下のコードを追加
dd($request->all());

登録フォームを送信して、genderが正しい値を持っているか確認

調査結果

添付からgenderフィールドには値が渡されている
それにも関わらず下記のサーバーエラーが発生している
Internet Server Error 500
スクリーンショット 2024-11-18 21.01.39.png

スクリーンショット 2024-11-18 21.03.20.png

調査内容2

モデルでジェンダーがfillableプロパティに含まれているか確認
⇨User.phpを確認したところ、含まれていなかった
下記にて修正したところ解決。

protected $fillable = [
    'name',
    'email',
    'password',
    'account_name',
    'instagram',
    'gender',
    'location',
    'profile_photo',
];

補足情報

  • fillable の役割
    fillable プロパティは、Eloquent の「一括代入 (Mass Assignment)」を使用する際に、どのフィールドを許可するかを指定します。このプロパティに指定していないフィールドは、自動的に無視されるため、データベースに保存されません。

今回のケースでは gender が fillable に追加されていなかったため、データベースに挿入されず、NOT NULL 制約によってエラーが発生していました。

変更した部分

app/Http/Controllers/Auth/RegisteredUserController.php

  // リクエスト内容を確認
        // dd($request->all());

        // バリデーション
        $request->validate([
            'account_name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:8|confirmed',
            'instagram' => 'nullable|string|max:255',
            // 'gender' => 'required|string',
            'gender' => 'required|in:male,female',
            'location' => 'nullable|string|max:255',
            'profile_photo' => 'nullable|image|mimes:jpg,jpeg,png|max:2048',
        ]);

        // プロフィール写真の保存処理
        $profilePhotoPath = null;
        if ($request->hasFile('profile_photo')) {
            $profilePhotoPath = $request->file('profile_photo')->store('profile_photos', 'public');
        }

        // ユーザー作成
        $user = User::create([
            'account_name' => $request->account_name,
            'name' => $request->account_name, // ここで `name` を設定
            'email' => $request->email,
            'password' => Hash::make($request->password),
            'instagram' => $request->instagram,
            'gender' => $request->gender, //この部分は正しい。
            'location' => $request->location,
            'profile_photo' => $profilePhotoPath,
        ]);

        // 登録イベント発火
        event(new Registered($user));

        // ログイン処理
        Auth::login($user);

        // ダッシュボードへのリダイレクト
        return redirect()->route('dashboard');
    }
}

app/Models/User.php

protected $fillable = [
        'name',
        'email',
        'password',
        'account_name',
        'instagram',
        'gender',
        'location',
        'profile_photo',
    ];

database/migrations/2024_11_17_205314_add_fields_to_users_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('account_name')->nullable()->after('id'); // NULLを許容する
            $table->string('instagram')->nullable()->after('email');
            $table->string('gender')->after('instagram');
            $table->string('location')->nullable()->after('gender'); // locationカラムを追加
            $table->string('profile_photo')->nullable()->after('location');
        });
    }

    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn(['account_name', 'instagram', 'gender', 'location', 'profile_photo']); // locationを含むすべてのカラムを削除
        });
    }
};

resources/views/auth/register.blade.php

<x-guest-layout>
    <div class="flex justify-center items-center min-h-screen bg-gray-100">
        <div class="w-full max-w-md bg-white p-6 rounded-lg shadow-md">
            <h2 class="text-center text-2xl font-bold mb-6">ユーザー登録</h2>

            <form method="POST" action="{{ route('register') }}" enctype="multipart/form-data" class="space-y-6">
                @csrf

                <!-- アカウント名 -->
                <div>
                    <x-input-label for="account_name" :value="__('アカウント名')" />
                    <x-text-input id="account_name" class="block mt-1 w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500" type="text" name="account_name" required autofocus />
                    <x-input-error :messages="$errors->get('account_name')" class="mt-2" />
                </div>

                <!-- メールアドレス -->
                <div>
                    <x-input-label for="email" :value="__('メールアドレス')" />
                    <x-text-input id="email" class="block mt-1 w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500" type="email" name="email" required />
                    <x-input-error :messages="$errors->get('email')" class="mt-2" />
                </div>

                <!-- パスワード -->
                <div>
                    <x-input-label for="password" :value="__('パスワード')" />
                    <x-text-input id="password" class="block mt-1 w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500" type="password" name="password" required />
                    <x-input-error :messages="$errors->get('password')" class="mt-2" />
                </div>

                <!-- パスワード確認用 -->
                <div>
                    <x-input-label for="password_confirmation" :value="__('パスワード(確認用)')" />
                    <x-text-input id="password_confirmation" class="block mt-1 w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500"
                        type="password"
                        name="password_confirmation"
                        required autocomplete="new-password" />
                    <x-input-error :messages="$errors->get('password_confirmation')" class="mt-2" />
                </div>


                <!-- Instagram URL -->
                <div>
                    <x-input-label for="instagram" :value="__('Instagram URL')" />
                    <x-text-input id="instagram" class="block mt-1 w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500" type="text" name="instagram" />
                    <x-input-error :messages="$errors->get('instagram')" class="mt-2" />
                </div>

                <!-- 性別 -->
                <div>
                    <x-input-label for="gender" :value="__('性別')" />
                    <select id="gender" name="gender" class="block mt-1 w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500">
                        <option value="male"></option>
                        <option value="female"></option>
                    </select>
                    <x-input-error :messages="$errors->get('gender')" class="mt-2" />
                </div>

                <!-- 写真 -->
                <div>
                    <x-input-label for="profile_photo" :value="__('写真を選択')" />
                    <input id="profile_photo" class="block mt-1 w-full border-gray-300 rounded-lg shadow-sm focus:border-indigo-500" type="file" name="profile_photo" accept="image/*">
                    <x-input-error :messages="$errors->get('profile_photo')" class="mt-2" />
                </div>

                <!-- 登録ボタン -->
                <div class="flex justify-center">
                    <x-primary-button class="w-full text-center">
                        {{ __('登録') }}
                    </x-primary-button>
                </div>
            </form>
        </div>
    </div>
</x-guest-layout>

次回実施内容

  • 投稿画面の作成

最後までご覧いただき本当にありがとうございました!!

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?