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) }}
保存できたか確認する
保存できたみたいです。
画像は、/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 のストレージに保存することは少ないと思いますが、久々に使ってみました。
とりあえず、Laravel のストレージに保存、最終的に S3 などに移行したいという場合は、image_url
を保存する段階で/storage
をプレフィックスで付けて呼び出す時に
<img src="{{ $user->image_url) }}" />
の方がフロント触らないので良いかもしれないです。プログラミングは今はこれで進むけど将来これになるかもみたいなのが多々あるので先を考えつつベストを目指したいっすね。
参考になれば幸いです。