ホーム > Laravel > Laravelでプロフィール編集機能を作る方法
Laravel

Laravelでプロフィール編集機能を作る方法

いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。

Laravel でプロフィール編集機能を作る方法についてまとめました

users テーブルに保存したい情報のカラムを追加する

本番環境で稼働していない場合

開発環境上でやり始めた場合は、既存のマイグレーションファイルに追記する感じで大丈夫です。

別テーブルに保存したい場合は新しいテーブルを作成してリレーションさせるのも良いと思いますが、今回は追記する形で進めます。

database/migrations/0001_01_01_000000_create_users_table.php

        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->string('image_url')->nullable(); //追加
            $table->string('self_introduction',2000)->nullable(); //追加
            $table->rememberToken();
            $table->timestamps();
        });

画像と自己紹介文がかけるように2つのカラムを追加しました。

以下のコマンドでデータベースに反映させます。お試し入力していたテストデータなどは消えますが、テストデータは基本的に Factory や Seeder を使ってコーディングで生成するようにしておきましょう。

php artisan migrate:fresh --seed

Laravel で Factory を使ってテストデータを作成する方法

本番環境で稼働している場合

本番環境で稼働している場合、さきほどの方法は使えません。

マイグレーションファイルは一度実行されたファイルの情報が残るため、追記したとしても2度と実行されることがありません。

ですので、新しいファイルを作成し、そこに追記する必要があります。

コマンドでファイルを生成します。

php artisan make:migration add_image_url_to_users_table

database/migrations/0001_01_01_000000_add_image_url_to_users_table.phpというファイルが作られるので、

    public function up(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('self_introduction',2000)->nullable()->after('password'); //追加
            $table->string('image_url')->nullable()->after('password'); //追加
        });
    }

    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn('image_url'); //追加
            $table->dropColumn('self_introduction'); //追加
        });
    }

コマンドでデータベースに反映させます。

php artisan migrate

Laravel のマイグレーションの after の順序を見やすくする方法

ルーティングを作成する

編集用ページと、編集の処理の2つのルーティングを作ります。

routes/web.php

use App\Http\Controllers\ProfileController;

Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');

コントローラーを作成する

コマンドでコントローラーを作成します。

ついでに、今回は画像はララベルのストレージを使うので、シンボリックリンクも作成します。

php artisan make:controller ProfileController
php artisan storage:link

作成されたコントローラーに書きます。

app/Http/Controllers/ProfileController


use App\Http\Requests\ProfileUpdateRequest; //useに追記

~~

    //編集ページ
    public function edit(Request $request)
    {
        return view('profile.edit', ['user' => $request->user()]);
    }

    //更新処理
    public function update(ProfileUpdateRequest $request)
    {
        $user = $request->user();

        $user->name = $request->name;
        $user->self_introduction = $request->self_introduction;

        $image = $request->file('image');

        if($image){
            $image_url = Storage::disk('public')->put('user_profile_image', $image, 'public');
            $user->image_url = $image_url;
        }

        if($user->isDirty()){
            $user->save();
        }

        return redirect()->route('profile.edit')->with('status', 'profile-updated');
    }

Vue と Laravel と S3 の環境で画像の保存をする方法

バリデーションの作成

コマンドでバリデーションのためのリクエストクラスを作ります。

php artisan make:request ProfileUpdateRequest

app/Http/Request/ProfileUpdateRequest.php

    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'image' => ['nullable','image','mimes:jpeg,jpg,png','max:10000'],
            'self_introduction' => ['nullable','string','max:2000']
        ];
    }

以上でバリデーションの設定が可能です。コントローラーの以下の部分で事前にこのクラスを使うように書かれています。

use App\Http\Requests\ProfileUpdateRequest; //useに追記

public function update(ProfileUpdateRequest $request)

【初心者向け】Laravel のフォームリクエストでバリデーションする方法

ビューの作成

resources/views/profile/edit.blade.phpというファイルを作成して、

<form
  method="post"
  action="{{ route('profile.update') }}"
  class="mt-6 space-y-6"
  enctype="multipart/form-data"
>
  @csrf
  <div>
    <label for="name">名前</label>
    <input
      id="name"
      name="name"
      type="text"
      class="mt-1 block w-full"
      value="{{ old('name', $user->name) }}"
      required
      autofocus
      autocomplete="name"
    />
    <ul class="text-sm text-red-600 space-y-1">
      @foreach ((array) $errors->get('name') as $message)
      <li>{{ $message }}</li>
      @endforeach
    </ul>
  </div>

  <div>
    <label for="image">画像</label>
    <input id="image" type="file" name="image" class="mt-1 block w-full" />
    <ul class="text-sm text-red-600 space-y-1">
      @foreach ((array) $errors->get('image') as $message)
      <li>{{ $message }}</li>
      @endforeach
    </ul>
  </div>
  <div>
    <label for="self_introduction">自己紹介</label>
    <textarea
      id="self_introduction"
      name="self_introduction"
      class="mt-1 block w-full"
    >
{{ old('self_introduction', $user->self_introduction) }}</textarea
    >
    <ul class="text-sm text-red-600 space-y-1">
      @foreach ((array) $errors->get('self_introduction') as $message)
      <li>{{ $message }}</li>
      @endforeach
    </ul>
  </div>
  <div class="flex items-center gap-4">
    <button>保存</button>
  </div>
</form>

バリデーションエラーの表示

この部分はバリデーションエラーになった時の表示

<ul class="text-sm text-red-600 space-y-1">
  @foreach ((array) $errors->get('self_introduction') as $message)
  <li>{{ $message }}</li>
  @endforeach
</ul>

入力の維持

バリデーションエラーなどで戻ってきた時、入力を維持するためにoldという関数があります。

{{ old('self_introduction', $user->self_introduction) }}

保存できたか確認する

laravel profile

保存できたみたいです。

画像は、/storage/app/public/user_profile_imageに保存されています。

データベースには、/storage/app/public/以降のパスが保存されます。

画像を表示したいとき

/storage/user_profile_image/***.pngこういうパスで呼び出せば表示できます。

/public/storage//storage/app/public/につながります。

なので、以下のようにすると呼び出せます。

<img src="{{ asset('storage/'.$user->image_url) }}" />

Laravel 11.x ファイルストレージ

まとめ

以上、プロフィールを編集する機能についてまとめてみました。

Laravel のストレージに保存することは少ないと思いますが、久々に使ってみました。

とりあえず、Laravel のストレージに保存、最終的に S3 などに移行したいという場合は、image_urlを保存する段階で/storageをプレフィックスで付けて呼び出す時に

<img src="{{ $user->image_url) }}" />

の方がフロント触らないので良いかもしれないです。プログラミングは今はこれで進むけど将来これになるかもみたいなのが多々あるので先を考えつつベストを目指したいっすね。

参考になれば幸いです。

フィードバックのお願い
この記事のフィードバックがありましたらYoutubeの適当な動画にコメントしていただいたり、お問い合わせからご連絡ください。