いろいろとすっ飛ばしてるこのLaravelをやってみる記事ですが、①と②も是非ご覧ください。
Laravelをやってみる① 設計編 Laravelをやってみる② 検索機能編最初に…
プロフィール編集機能をつけていきます。編集画面にて、名前の変更とプロフィール画像の追加ができるようにします。
Laravelでは勝手にusersテーブルが作られます。設計の段階ではそのままにしておきましたので、画像のパスを入れるカラムがありません。
マイグレーションで追加してあげましょう。ターミナルで以下を。
$ php artisan make:migration add_image_column_to_users_table --table=users
マイグレーションファイルが追加されるので、以下のように編集します。
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('image')->nullable()->after('password');
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('image');
});
}
新規登録の際は画像をアップロードしないので、nullable()としておきます。また、このままだとupdated_atカラムの次に追加されるので、after(‘password’)とし、passwordカラムの次に追加するようにします。
downメソッドではimageカラムを消す処理を書きます。
$ php artisan migrate
ターミナルでマイグレートを行い、カラムが追加されたか確認しましょう。
できていたら、ロールバックできるかの確認。
$ php artisan migrate:rollback
カラムが消えている事を確認したら、再度以下を。
$ php artisan migrate
これでusersテーブルにimageカラムが追加されました。
お次は…
編集ページの画面モックです。
ここを表示するためには、Routingで
Route::get('/edit', 'UserController@index')->name('user.index');
/editにアクセスした時にUserControllerのindexメソッドを呼んであげます。
UserControllerのindexメソッドでは、viewを表示する処理をしますが、それと同時にユーザーの登録情報も一緒に渡してあげます。
public function index()
{
$authUser = Auth::user();
return view('user.index', compact('authUser'));
}
これにより、userディレクトリのindex.blade.phpにて$authUserでそのユーザー情報が取れるようになりました。
以下がviews/user/index.blade.phpです。
<form method="POST" action="{{ route('user.update') }}" enctype="multipart/form-data">
@csrf
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('ニックネーム') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ $authUser->name }}" required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="inputFile" class="col-md-4 col-form-label text-md-right">プロフィール画像</label>
<div class="input-group col-md-6">
<div class="custom-file">
<input type="file" class="custom-file-input" id="inputFile" name="image">
<label class="custom-file-label" for="inputFile" data-browse="参照">選択かドロップ</label>
</div>
<div class="input-group-append">
<button type="button" class="btn btn-outline-secondary input-group-text" id="inputFileReset">取消</button>
</div>
</div>
</div>
@error('image')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
<div class="form-group row">
<div class="col-md-6 offset-md-6 prof-img">
@if($authUser->image !== null)
<img src="/storage/profile_images/{{ $authUser->image }}" class="button" style="object-fit: cover">
@else
<img src="../img/noimage.jpeg" class="button">
@endif
</div>
</div>
<div class="form-group row mb-0 mt-4">
<div class="col-md-8 offset-md-2">
<button type="submit" class="btn btn-info btn-block">
{{ __('ニックネームと画像を変更する') }}
</button>
</div>
</div>
</form>
ニックネーム欄に登録された名前が出ていると思います。
ここまでが初期画面です。
ここから、「変更する」ボタンを押した時の処理を書いていきます。
変更ボタン押下後の処理
まずRoutingですが、
Route::post('/update', 'UserController@update')->name('user.update');
このようにします。views/user/index.blade.phpのformのactionでroute(‘user.update’)を指定しています。POST送信されたときにここに処理がいきます。
UserControllerのupdateメソッドを書いていきます。
public function update(UserRequest $request)
{
$authUser = Auth::user();
$authUser->name = $request->input('name');
$uploadFile = $request->file('image');
if (!empty($uploadFile)) {
$thumbnailName = $request->file('image')->hashName();
$request->file('image')->storeAs('public/profile_images', $thumbnailName);
$authUser->image = $thumbnailName;
}
$authUser->save();
return redirect('user/edit')->with('flash_message', '変更しました');
}
今回はバリデーションをかけているため、引数がRequestではなく、UserRequestになっています。
$ php artisan make:request UserRequest
UserRequestクラスを作ったら以下のように修正します。
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|max:255',
'image' => 'file|image|mimes:jpeg,png,jpg,gif|max:2048',
];
}
ルールについてはhttps://readouble.com/laravel/6.x/ja/validation.htmlに書いてあります。
さて、UserControllerのupdateメソッドの説明に戻ります。
$authUser = Auth::user();
$authUser->name = $request->input('name');
上記コードは認証中のユーザー情報をもってきて、そこに入力された値を突っ込みます。
また、画像アップロードですが生PHPではややこしかったんですが、
$uploadFile = $request->file('image');
if (!empty($uploadFile)) {
$thumbnailName = $request->file('image')->hashName();
$request->file('image')->storeAs('public/profile_images', $thumbnailName);
$authUser->image = $thumbnailName;
}
上記コードは画像がアップされていたらの処理です。
アップされていたら、hashName()で、ファイル名をハッシュ化します。これは後述のstoreメソッドやstoreAsメソッド内でもしてくれますが、今回はDBに保存するために先にhash化しています。
ハッシュ化したものをstoreAsメソッドで保存します。storeメソッドはパス名のみ指定するのに対し、storeAsではファイル名も指定できます。
先ほどハッシュ化したファイル名を第2引数に渡します。そして、最後にusersのimageカラムにそのファイル名を上書きします。
save()を書いて、redirectします。
画像アップし、usersテーブルに保存されていたら成功です。