Laravel Collectionのfindメソッドの使い方|「undefined method」エラーの原因と対処

基本文法・構文ガイド

$collection->find(1)」を試して Call to undefined method Illuminate\Support\Collection::find() というエラーに遭遇した方は多いはずです。実はLaravelのfindメソッドは、Eloquentのクエリ結果(Eloquent Collection)専用のメソッドで、collect()で作った通常のCollectionには存在しません。この記事では、findメソッドが実際にどこで使えるのか、通常のCollectionで同じことをしたい場合の代替方法まで、具体例を交えて正確に解説します。

要点(TL;DR)

  • find()Eloquent Collection(クエリ結果)専用のメソッド。collect([...])で作った通常のCollectionには存在しない
  • Eloquentでの基本形:$users->find(1) → 主キーが一致するモデルまたはnullを返す
  • 通常のCollectionでキー検索したい場合はfirstWherefirstを使う

findメソッドとは(Eloquent Collection専用)

findは、Illuminate\Database\Eloquent\CollectionModel::all()get()などクエリの実行結果として得られるコレクション)に定義されたメソッドです。基底クラスであるIlluminate\Support\Collectioncollect()で作る通常のコレクション)には実装されていません。渡した主キー(プライマリキー)と一致するモデルを、コレクションの中から探して返します。

構文 / シグネチャ

find(mixed $key, mixed $default = null): Model|static|null
  • $key:主キーの値。配列Arrayableを渡すと複数件検索になる
  • 戻り値:単一キー指定時はモデルまたは$default(既定null)。配列指定時は一致したモデルだけを含むCollection

使用例(正しい使い方)

単一IDで検索

use App\Models\User;

$users = User::all(); // Eloquent Collection

$user = $users->find(1); // 主キー=1のモデル、なければ null

複数IDで検索(配列を渡す)

$matched = $users->find([1, 2, 5]); // 一致した要素だけのCollection

見つからない場合のデフォルト値

$user = $users->find(999, 'not-found'); // 一致しなければ 'not-found' を返す

通常のCollectionで同じことをしたい場合

collect([...])で作った通常のCollectionに対してfindを呼ぶと、次のように致命的エラーになります。

$collection = collect([
    ['id' => 1, 'name' => 'John'],
    ['id' => 2, 'name' => 'Jane'],
]);

$collection->find(1);
// Error: Call to undefined method Illuminate\Support\Collection::find()

この場合はfirstWhereまたはfirstで代替します。

// キー=値で最初の一致を取得(推奨・簡潔)
$item = $collection->firstWhere('id', 1);
// ['id' => 1, 'name' => 'John']

// コールバックで柔軟な条件指定
$item = $collection->first(fn ($item) => $item['id'] === 1);

複数件を条件で絞り込みたい場合はfilterを使います。

$filtered = $collection->filter(fn ($item) => $item['id'] > 1);

よくある落とし穴・注意

  • 「Collectionにfindがない」エラーの原因collect()由来の通常Collectionにはfindが存在しない。Eloquentクエリ結果(get()/all())かどうかを確認する
  • find()は配列に対しても動く:主キーの配列を渡すとCollectionが返る点に注意(単一キーとは戻り値の型が変わる)
  • find()はメモリ内検索:すでに取得済みのコレクションを走査するだけで、DBへの再クエリは発生しない。DB側で1件だけ取得したい場合はModel::find($id)(クエリビルダの静的メソッド)の方が効率的
  • 大規模データでのパフォーマンスfind/firstWhereとも内部的には線形探索(O(n))。事前にDB側で絞り込んでからコレクション化すると高速

代替・関連メソッドとの比較

メソッド使えるコレクション用途
findEloquent Collectionのみ主キーでモデルを検索
firstWhere通常のCollection / Eloquent Collectionキー=値、または演算子で最初の一致を検索
first通常のCollection / Eloquent Collectionコールバックで柔軟に最初の一致を検索
filter通常のCollection / Eloquent Collection条件に合う複数要素を抽出
contains通常のCollection / Eloquent Collection該当要素の有無だけを真偽値で判定

よくある質問(FAQ)

Q. なぜ「Call to undefined method Collection::find()」が出るのですか?

A. findはEloquent Collection(クエリ結果)専用のメソッドで、collect([...])で作った通常のCollectionには実装されていないためです。通常のCollectionでキー検索したい場合はfirstWherefirstを使ってください。

Q. find()に配列を渡すとどうなりますか?

A. 複数の主キーを配列で渡すと、一致したモデルだけを含むCollectionが返ります。単一キーを渡した場合の戻り値(モデルまたはnull)とは型が異なる点に注意してください。

Q. find()とModel::find()は同じですか?

A. 別物です。$users->find(1)(Collectionのfind)はすでに取得済みのコレクションをメモリ上で走査します。一方User::find(1)はクエリビルダの静的メソッドで、DBに対してWHERE id = 1のクエリを実行します。1件だけ欲しい場合は後者の方が効率的です。

関連記事

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする

コメント