LaravelのBreezeのログイン機能で作ったユーザー情報の編集機能

LaravelのBreezeのログイン機能で作ったユーザー情報の編集機能

961 回閲覧されました

みなさんこんにちは、jonioです。

今回はLaravelのBreezeでログイン機能を実装してから作ったユーザーのアカウント情報を更新する方法を解説します。

またパスワードを変更した際にパスワードをランダムな文字列に変更して他の人からパスワードがわからなくするハッシュ化の解説もします。

Laravelのバージョン

Laravelのバージョンは8です。

プロフィールを更新するページの表示

まずはプロフィールを更新するページを表示する為の設定をします。

web.php

web.phpに下記の記述をします。

Route::controller(ProfileController::class)->group(function(){
    Route::get('/profile/{user}/edit', 'edit')->name('profile.edit');
});

ProfileController.php

ProfileController.phpを作成して下記の記述をします。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;                                   //この行を追加

class ProfileController extends Controller
{


    //ここから追加
    public function edit(User $user){
        return view('profile.edit', compact('user'));
    }
    //ここまで追加
    
    
}

編集ページへのリンク

編集ページに移動する為のリンクの記述をします、リンクを付けたいビューに下記の記述をします。

今のままではプロフィールを編集するページへのリンクがないので作成します。

<a href="{{route('profile.edit', auth()->user()->id)}}">プロフィールの編集</a>

ビュー

プロフィールを編集するビュー(edit.blade.php)に下記の記述をします。

<form action="{{route('profile.update', $user)}}">
    @csrf
    @method('put')
    <div class="form-group">
        <label for="name">名前</label>
        <input type="text" name="name" class="form-controller" id="name" value="{{old('name', $user->name)}}">
    </div>
    <div class="form-group">
        <label for="email">メールアドレス</label>
        <input type="text" name="email" class="form-controller" id="email" value="{{old('email', $user->email)}}">
    </div>
    <div class="form-group">
        <label for="password">パスワード</label>
        <input type="password" name="password" class="form-controller" id="password" value="{{old('password', $user->password)}}">
    </div>
    <div class="form-group">
    <div class="form-group">
        <label for="password">パスワード再入力</label>
        <input id="password-confirm" type="password" class="form-control" name="password_confirmation" placeholder="パスワードを再入力してください" required autocomplete="new-password">
    </div>
    <button type="submit" class="btn btn-success">送信する</button>
</form>

このページはBootStrapで見た目を整えようとしたのですがまだCDNを使ってない状態が下記になります。

6行目・10行目・14行目のvalue属性にold関数があるのでユーザーアカウントを作成した時の名前・メールアドレス・パスワードが入力された状態になります。

次は更新機能を実装します。

更新機能

更新のページを表示した時と同じようにweb.php・ProfileController.phpに記述します。

web.php

web.phpに追記します。

Route::controller(ProfileController::class)->group(function(){
    //プロフィールの編集ページ
    Route::get('/profile/{user}/edit', 'edit')->name('profile.edit');
    
    //プロフィールの編集を保存
    Route::get('/profile/{user}', 'update')->name('profile.update');       //この行を追加
});

ProfileController.php

ProfileController.phpに追記します。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;


//ここから追加
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Hash;
//ここまで追加


class ProfileController extends Controller
{
    public function edit(User $user){
        return view('profile.edit', compact('user'));
    }


    //ここから追加
    public function update(User $user, Request $request){
        $inputs = request()->validate([
            'name' => 'required|max:255',
            'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)],
            'password' => 'required|confirmed|max:255|min:8',
            'password_confirmation' => 'required|same:password'
        ]);

        $inputs['password'] = Hash::make($inputs['password']);

        $user->update($inputs);

        return back()->with('message', 'ユーザー情報を更新しました');
    }
    //ここまで追加
    
    
}

10行目はBREEZEのデフォルトのバリデーションルールを変更する為に使い26行目の「Rule::unique(‘users’)->ignore($user->id)」に適用します。

「Rule::unique(‘users’)->ignore($user->id)」が何を意味しているのか説明します。

「Rule::unique(‘users’)->ignore($user->id)」

Breezeでログイン機能を作ってusersテーブルができた時点でメールアドレスは同じ値を使用してはいけないとusersテーブルを作成するマイグレーションファイル(下記参照)に記載されています。

<?php

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

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        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->rememberToken();
            $table->timestamps();
        });
    }



}

ユーザー情報を編集する時も編集前と同じメールアドレスを使用することができません。

そのルールをユーザー情報を編集する時のみ無効にする為下記に記述をします。

Rule::unique('users')->ignore($user->id)]

「users」はテーブル名です。

「Rule::unique(‘users’)」が「usersテーブルのバリデーションルール」という意味で「->ignore($user->id)」が「現在のユーザー(編集をしているユーザー)の場合は除外する」という意味です。

パスワードのハッシュ化

話をProfileController.phpに戻して11行目はパスワードのハッシュ化をすることができるようにする為に記述します。

パスワードのハッシュ化は31行目の「Hash::make($inputs[‘password’]);」で行っています。

ハッシュ化をする時の記述は下記になります。

Hash::make(name属性の値);

「name属性の値」に当たるのが今回だとビューのパスワードを入力するフォームのname属性(下記参照)になります。

<div class="form-group">
  <label for="password">パスワード</label>
  <input type="password" name="password" class="form-controller" id="password" value="{{old('password', $user->password)}}">        //この行
</div>

これでユーザー情報を変更する機能の実装が完成です。

コントローラーのスリム化

ProfileController.phpにユーザー情報を変更する為の記述をしましたがデータベースに接続するのはモデルの役割なので処理はモデルに書くのが適切だと思います。

これをすることによってコントローラーの記述量を減らします。

User.php

コントローラーに書いたユーザー情報を変更する記述をユーザーのモデルであるUser.phpに記述します。

<?php

namespace App\Models;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;


class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function profileUpdate($request){

        $user = Auth::user();

        $inputs = request()->validate([
            'name' => 'required|max:255',
            'email' => ['required', 'email', 'max:255', Rule::unique('users')->ignore($user->id)],
            'password' => 'required|confirmed|max:255|min:8',
            'password_confirmation' => 'required|same:password'
        ]);

        $inputs['password'] = Hash::make($inputs['password']);

        $this->update($inputs);
    }
}

11行目はデフォルトのUser.phpにはないのですがログインしているユーザーを取得するのに必要なので記述しています。

49行目〜63行目がユーザー情報を編集する為の記述です。

Profileコントローラーに記述していた時とほとんど同じです。

51行目でログインしているユーザーを取得していますがコントローラーでは必要ないけどモデルでは必要になるみたいです。

そしてProfileコントローラーでモデルのprofileUpdateメソッドを使います。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
//use Illuminate\Support\Facades\Hash;                この行は削除    


class ProfileController extends Controller
{
    public function edit(User $user){
        return view('profile.edit', compact('user'));
    }

    public function update(User $user, Request $request){

        $user->profileUpdate($request);

        return back()->with('message', 'ユーザー情報を更新しました');
    }
}

ユーザー情報を変更しているのは18行目ですがコントローラーがかなりスッキリしました。

これで完成です。