Laravelでinput:checkboxのデフォルトでのチェックを実装する

ご存知の通りHTMLの仕様バグによりinput:checkboxは未チェック時、nameも送ってくれない。通常なら以下のようにして、フォームエラー時の再チェックを実装する。

<input type="checkbox" name="example" value="1" {!! old('example') == 1 ? 'checked="checked" : '' !!}>

デフォルトが未チェックであればこれで問題ないが、デフォルトでチェック状態にしたい場合はこれでは駄目だ。以下のように、引数なしのold()で、通常のフォーム表示なのか、フォームエラー時にリダイレクトされたのかを判断する。

<input type="checkbox" name="example" value="1" {!! empty(old()) || old('example') == 1 ? 'checked="checked"' : '' !!}>

もちろんこのチェックボックス以外のデータがない場合もempty(old())が真になるが、最低でもCSRFチェック用のフィールドは存在するため問題にはならないはず。

引数なしのold()がなにを返すかについてはドキュメントにはないので、以下のようにソースコードを辿る。

  1. old()Illuminate/Foundation/helpers.php::old().
  2. そこから、Illuminate\Http\Request::old()が呼び出されていて、その実体はIlluminate\Http\Concerns\InteractsWithFlashData::old()
  3. InteractsWithFlashData::old()からIlluminate\Session\Store::getOldInput()が呼び出されている。
  4. getOldInput()ではArr::get()されている。
  5. Arr::get()$keyが空の場合は$arrayをそのまま返している。

意外と道のりが長くてびっくりした。