33.

Laravel コレクション先頭/末尾追加完全ガイド|select 結果に「選択してください」を加える

編集
この記事の要点
  • 先頭に追加: $collection->prepend($value, $key)
  • 末尾に追加: $collection->push($value) または put($key, $value)
  • 結合: $collection->concat([...]) / merge([...])
  • HTML <select> の先頭に「選択してください」を入れる定番パターン
  • Eloquent + Collection で連想配列 (id => name) を作るときは pluck()prepend()

結論: select 用配列の作り方

Laravel で <select> のオプション一覧を作るとき、先頭に「選択してください」のような空オプションを入れたいケースは頻出。コレクションの prepend() を使うのが定石です:

use App\Models\Category;

// id => name の連想配列を取得
$categories = Category::pluck('name', 'id');
// [1 => '雑貨', 2 => '食品', 3 => '家電']

// 先頭に「選択してください」を追加
$options = $categories->prepend('-- 選択してください --', '');
// ['' => '-- 選択してください --', 1 => '雑貨', 2 => '食品', 3 => '家電']

// Blade で使う
// {{ Form::select('category_id', $options, null, ['class' => 'form-control']) }}

Collection の追加系メソッド一覧

メソッド位置キー指定
prepend($value, $key = null)先頭$c->prepend('A', 0)
push($value)末尾不可(自動採番)$c->push('Z')
put($key, $value)末尾(または上書き)必須$c->put('z', 'Z')
add($value)末尾不可$c->add('Z')
concat($source)末尾に結合キー振り直し$c->concat([10, 20])
merge($items)末尾結合(キー保持)同キーは上書き$c->merge(['a' => 1])
union($items)末尾結合(既存優先)同キーは無視$c->union(['a' => 9])

prepend の使い方

use Illuminate\Support\Collection;

$c = collect([1 => 'A', 2 => 'B', 3 => 'C']);

// キー指定なし(自動で 0 番)
$c->prepend('Z');
// [0 => 'Z', 1 => 'A', 2 => 'B', 3 => 'C']

// キー指定あり
$c->prepend('Z', 'zero');
// ['zero' => 'Z', 1 => 'A', 2 => 'B', 3 => 'C']

// 空文字キーで select 用先頭に
$c->prepend('選択してください', '');
// ['' => '選択してください', 1 => 'A', 2 => 'B', 3 => 'C']

push / put / add の違い

$c = collect(['a' => 1, 'b' => 2]);

// push : 末尾に追加。キー指定不可(連番)
$c->push(99);
// ['a' => 1, 'b' => 2, 0 => 99]

// add : push と同等(メソッド名違いの別名)
$c->add(99);

// put : キー指定必須。同じキーがあれば上書き
$c->put('c', 3);
// ['a' => 1, 'b' => 2, 'c' => 3]

$c->put('a', 999);  // 上書き
// ['a' => 999, 'b' => 2, ...]

concat / merge / union の違い

$a = collect(['x' => 1, 'y' => 2]);
$b = ['y' => 20, 'z' => 30];

// concat : キーを振り直して結合
$a->concat($b);
// [0 => 1, 1 => 2, 2 => 20, 3 => 30]

// merge : キー保持、同キーは引数側で上書き
$a->merge($b);
// ['x' => 1, 'y' => 20, 'z' => 30]

// union : キー保持、同キーは元側を優先
$a->union($b);
// ['x' => 1, 'y' => 2, 'z' => 30]

HTML <select> を組み立てる

純粋 HTML 出力

// Controller
$options = Category::pluck('name', 'id')
    ->prepend('-- 選択してください --', '');

return view('items.create', compact('options'));
{{-- Blade: items/create.blade.php --}}
<select name="category_id" class="form-control">
@foreach ($options as $value => $label)
    <option value="{{ $value }}" @selected(old('category_id') == $value)>
        {{ $label }}
    </option>
@endforeach
</select>

Laravel Collective Form 利用時

{{-- composer require laravelcollective/html --}}
{!! Form::select('category_id', $options, old('category_id'), [
    'class' => 'form-control',
]) !!}

{{-- $options は連想配列 / Collection どちらも可 --}}

optgroup(分類された select)

// 親子構造で送る
$groups = [
    '食品' => [1 => 'パン', 2 => '米'],
    '雑貨' => [3 => 'ノート', 4 => 'ペン'],
];
<select name="item_id">
    <option value="">-- 選択してください --</option>
@foreach ($groups as $groupLabel => $items)
    <optgroup label="{{ $groupLabel }}">
        @foreach ($items as $id => $name)
            <option value="{{ $id }}">{{ $name }}</option>
        @endforeach
    </optgroup>
@endforeach
</select>

Eloquent + Collection の合わせ技

use App\Models\Prefecture;

// 都道府県の select オプション(先頭に空欄)
$prefs = Prefecture::orderBy('code')
    ->pluck('name', 'code')
    ->prepend('-- 選択してください --', '');

// 「その他」を末尾に追加
$prefs->put('99', 'その他');

// 結果
// ['' => '-- 選択してください --',
//  '01' => '北海道', '02' => '青森県', ..., '47' => '沖縄県',
//  '99' => 'その他']

@forelse で「データなし」のとき

{{-- データが空のときは「カテゴリがありません」を表示 --}}
@forelse ($categories as $cat)
    <option value="{{ $cat->id }}">{{ $cat->name }}</option>
@empty
    <option value="" disabled>カテゴリがありません</option>
@endforelse

キーを文字列で揃えるテクニック

HTML form の value は常に文字列で送られるため、id を数値で持っていると old() の比較に == が必要です。型を揃えると安心:

$options = Category::pluck('name', 'id')
    ->mapWithKeys(fn ($name, $id) => [(string)$id => $name])
    ->prepend('-- 選択してください --', '');

FAQ

Q: 配列のまま末尾に値を追加したい
A: PHP 配列なら $arr[] = $value で末尾追加、array_unshift($arr, $value) で先頭追加。Collection に変換せず素のままでも可。

Q: prepend のキーが 0'' で被ったらどうなる?
A: 既存キーが上書きされます。意図しないなら明示的にユニークキー('__placeholder__' 等)を指定。

Q: select の選択値を保持したい (old())
A: @selected(old('category_id') == $value) または{{ Form::select(..., old('category_id') ?? $model->category_id, ...) }}。型に注意。

Q: ページネーション結果に「全件」を追加したい
A: ページネーションオブジェクトは Collection ではないので、->items() で配列を取り出してから操作するか、Collection で先に組み立てた後ページング。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. インストールと設定
  2. クイックスタート & チュートリアル(初心者向け)
  3. クイックスタート & チュートリアル(中級者向け)
  4. ルーティング
  5. Bladeテンプレート(ビュー/レイアウト)
  6. コントローラー
  7. マイグレーションとテーブル定義
  8. データベースの設定
  9. Eloquentモデル (ORM)
  10. SQLとクエリビルダー
  11. バリデーション
  12. .envファイルの設定値へのアクセス
  13. 動作環境による分岐処理
  14. configフォルダ配下の設定値へのアクセス
  15. assetヘルパーを利用したpublicフォルダへのアクセス
  16. storageフォルダへのアクセス
  17. アプリケーション名の変更
  18. メンテナンス
  19. ログイン画面(認証システム)の作成
  20. ログインの必須化
  21. ログインユーザー情報の取得
  22. ルートの認証化
  23. 本番サーバーへのデプロイ方法
  24. 多言語化
  25. csrf_field
  26. ファイルのダウンロード
  27. CSVのアップロードおよび読み込み(maatwebsite/excel)
  28. ページタイトルの設定
  29. コマンド一覧
  30. エラー一覧
  31. SQLの実行ログ出力方法
  32. キャッシュのクリア
  33. Selectの結果の最初もしくは最後に任意の値を追加する方法
  34. ajaxでPOST通信する際の注意点
  35. ソーシャルログインの実装
  36. セッション情報の確認
  37. ログイン、ユーザー登録、パスワードリセット後のリダイレクト先の変更方法
  38. redirectやreturn viewにメッセージを付与する方法
  39. クッキー(cookie)の設定と取得
  40. クラスの再読み込み
  41. csrfの有効時間を変更する方法
  42. ViewComposerを用いてviewに共通の値を付与する方法
  43. View::shareを用いて共通の値を各ビューに渡す方法
  44. ミドルウェアを用いた処理の共通化
  45. Middleware内でAuth::check()などを使用する方法
  46. Controller以外でリダイレクトする方法
  47. セッションの値の取得/保存/更新/削除
  48. $requestの値を変更する方法
  49. 常時SSL化
  50. ページング(ページネーション)をする方法
  51. vue.jsとの連携
  52. Vue.jsと連携するSPA実行環境構築
  53. .envの値をvue.jsで参照する方法
  54. vue.jsを本番環境にリリースする方法
  55. could not find driver(Windows, MySQL編)

最近更新/作成されたページ