Laravel と checkbox と old() の話
例えば
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" name="is_admin" id="is_admin">
<label class="form-check-label" for="is_admin">管理者</label>
</div>
このようなチェックボックスがあるユーザー情報の編集画面を想定したときに、「初めて編集画面を開いたときには DB から取得した $user->is_admin
の値に基づいたチェック状態で表示し、更新ボタンを押してバリデーションエラーが発生したときには、最後の入力に応じたチェック状態で表示する」みたいな実装をすることが多いと思います。
このような場合に、単純に
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" name="is_admin" id="is_admin" @if (old('is_admin', $user->is_admin) == 1) checked @endif>
<label class="form-check-label" for="is_admin">管理者</label>
</div>
としても、$user->is_admin
が 1 で、直近の入力ではチェックボックスがオフの場合、チェックボックスをオフにすることができません。チェックボックスがオフの状態で送信すると、old('is_admin')
は null となり、old('is_admin', $user->is_admin)
は、デフォルト値である $user->is_admin
の値になってしまうからです。
このような場合、コントローラー側で少し値を加工してやるとうまく扱うことができます。
public function update(Request $request, User $user)
{
$request->merge([
'is_admin' => $request->boolean('is_admin') ? 1 : 0,
]);
$validated_data = $request->validate([
'name' => ['required'],
'is_admin' => ['boolean'],
]);
$user->fill($validated_data)->save();
}
以前に紹介したフォームリクエストの prepareForValidation
を使っても同様のことができますが、今回くらいの処理であれば、merge
メソッドを使ったほうが手っ取り早いかと。値を加工して merge
メソッドでリクエストに戻してやることで、バリデートもしやすくなりますし、old
ヘルパでも扱いやすくなります。
ディスカッション
コメント一覧
まだ、コメントがありません