やりたいこと
未入力の状態でフォームを送信したとき、空文字の値を入れたい

変更前のソースコード
<form method="POST" action="{{ route('profile.update') }}">
@csrf
@method('patch')
<div><label>名前:<input type="text" name="name" value="{{ $user->name }}"></label></div>
<div>プロフィール:<br>
<textarea name="profile" rows="10" cols="30">{{ $user->profile }}</textarea>
</div>
<input type="submit" value="更新">
</form>
public function rules()
{
return [
'name' => ['required', 'max:255'],
'profile' => ['max:1000'],
];
}
public function update(ProfileRequest $request)
{
$user = \Auth::user();
$user->update($request->only([
'name',
'profile',
]));
session()->flash('success', 'プロフィールを編集しました。');
return redirect()->route('users.show', \Auth::user() );
}
不具合
未入力状態でフォームを送信すると
システムエラー(Column 'profile' cannot be null)が発生する。
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'profile' cannot be null (SQL: update users set profile = ?, users.updated_at = 2023-02-09 12:01:24 where id = 6)
なんか勝手にnullに変換されてるんですけど。。。
原因
Kernelクラスで空文字を自動でnullに変換しているみたい。
入力のトリムと正規化
デフォルトでは、LaravelはアプリケーションのグローバルミドルウェアスタックにApp\Http\Middleware\TrimStringsとIlluminate\Foundation\Http\Middleware\ConvertEmptyStringsToNullミドルウェアを含めています。これらのミドルウェアは、App\Http\Kernelクラスによってグローバルミドルウェアスタックにリストされています。これらのミドルウェアは、リクエストに応じてすべての受信文字列フィールドを自動的にトリミングし、空の文字列フィールドをnullに変換します。これにより、ルートとコントローラでのこれらの正規化について心配する必要がなくなります。
(参照:入力のトリムと正規化)
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
犯人はあなたですね「ConvertEmptyStringsToNull::class」
解決策
nullを空文字に変換する場合
public function update(ProfileRequest $request)
{
$user = \Auth::user();
- $user->update($request->only([
- 'name',
- 'profile',
- ]));
+ $user->update([
+ 'name' => $request->input('name'),
+ 'profile' => $request->input('profile') ?? '',
+ ]);
session()->flash('success', 'プロフィールを編集しました。');
return redirect()->route('users.show', \Auth::user() );
}
変更点1:null判定後空文字入力
$request->input('profile') ?? '',
requestで入力された文字が入力されていた場合、そのまま入力。
requestで入力された文字が未入力の場合、''(空文字)入力。
- ??演算子

変更点2:onlyメソッドの削除
update([
onlyメソッドは連想配列のキーと値がセットになって渡されるそう。
フォームの内容をそのまま渡さない場合は個別に指定してやる。
onlyメソッドを使っている場合は、代入できない。
$user->update($request->only([
'name',
'profile' => $request->input('profile') ?? '',
]));
nullを許可したい場合
まとめ
- リクエストフォームが未入力の場合、自動でnullに変換される
- 別にnullでもいい場合は、参照:https://tech.amefure.com/php-laravel-blank-null
- nullを空文字として入力したい場合、??演算子を使う
- onlyメソッドはキーと値をセットで渡す
- フォームの内容をそのまま渡さない場合は個別に指定してやる
- chatGPT半端ないって
参考文献
- 公式ドキュメント
- nullを許可する場合
- 入力値が空かどうかの判別したい場合