Eloquent のコレクション
Eloquent が複数のモデルを返すときに使うコレクションの特別なメソッドを一覧で説明し、自分専用のコレクションを使う方法も紹介します。
Eloquent で、複数のモデルを返すメソッド(get や、リレーションで取り出した結果など)は、Illuminate\Database\Eloquent\Collection というクラスを返します。コレクションは、配列を便利に扱うための入れ物です。モデルがたくさん入った、特別な箱だと考えてください。
Eloquent のコレクションは、Laravel の基本のコレクションを受け継いでいます。そのため、モデルの配列を扱う、たくさんのメソッドが、最初から使えます。
コレクションは、くり返しもできるので、ふつうの PHP の配列のように、ループで回せます。
use App\Models\User;
$users = User::where('active', 1)->get();
foreach ($users as $user) {
echo $user->name;
}
ただし、コレクションは配列よりずっと強力で、map や reduce(値を変えたり、1つにまとめたりする処理)を、つなげて書けます。たとえば、有効でないモデルを取り除いて、残りのユーザーの名前を集める例です。
$names = User::all()->reject(function (User $user) {
return $user->active === false;
})->map(function (User $user) {
return $user->name;
});
基本のコレクションに変わるとき#
Eloquent のコレクションのメソッドの多くは、新しい Eloquent のコレクションを返します。ただし、collapse・flatten・flip・keys・pluck・zip は、基本のコレクションを返します。また、map の結果に、Eloquent のモデルが1つも入っていないときも、基本のコレクションに変わります。
使えるメソッド#
Eloquent のコレクションは、どれも基本のコレクションを受け継いでいるので、基本のクラスの強力なメソッドは、すべて使えます。
さらに、Illuminate\Database\Eloquent\Collection には、モデルのコレクションを扱うための、上乗せのメソッドがあります。多くは Illuminate\Database\Eloquent\Collection を返しますが、pluck など、Illuminate\Support\Collection を返すものもあります。
| メソッド | 働き |
|---|---|
append |
全部のモデルに、追加する属性を決める |
contains |
モデルがコレクションに入っているか調べる |
diff |
渡したコレクションにないモデルを返す |
except |
渡した主キーを持たないモデルを返す |
find |
主キーが合うモデルを返す |
findOrFail |
主キーが合うモデルを返す。なければ例外を投げる |
fresh |
全部のモデルを、データベースから取り直す |
intersect |
渡したコレクションにもあるモデルを返す |
load |
リレーションを、全部のモデルにまとめて読み込む |
loadMissing |
まだ読み込んでいないリレーションだけを読み込む |
modelKeys |
全部のモデルの主キーを返す |
makeVisible |
ふだんは隠れている属性を、見えるようにする |
makeHidden |
ふだんは見える属性を、隠す |
mergeVisible |
いまの見える属性は残して、見える属性を足す |
mergeHidden |
いまの隠す属性は残して、隠す属性を足す |
only |
渡した主キーを持つモデルだけを返す |
partition |
条件で、2つのコレクションに分ける |
setAppends |
追加する属性を、一時的に置き換える |
setVisible |
見える属性を、一時的に置き換える |
setHidden |
隠す属性を、一時的に置き換える |
toQuery |
コレクションのモデルの主キーで絞った問い合わせを返す |
unique |
重なりのないモデルだけを返す |
withoutAppends |
追加する属性を、一時的に全部なくす |
append#
append は、コレクションの全部のモデルに、追加する属性(配列や JSON にするとき、足して出す値)を決めます。属性の配列か、属性1つを渡します。
$users->append('team');
$users->append(['team', 'is_admin']);
contains#
contains は、モデルがコレクションに入っているかを調べます。主キーか、モデルを渡します。
$users->contains(1);
$users->contains(User::find(1));
diff#
diff は、渡したコレクションにないモデルを全部返します。
use App\Models\User;
$users = $users->diff(User::whereIn('id', [1, 2, 3])->get());
except#
except は、渡した主キーを持たないモデルを全部返します。
$users = $users->except([1, 2, 3]);
find#
find は、渡した主キーを持つモデルを返します。モデルを渡したときは、そのモデルの主キーと合うモデルを返そうとします。主キーの配列を渡すと、その配列にある主キーを持つモデルを、全部返します。
$users = User::all();
$user = $users->find(1);
findOrFail#
findOrFail は、渡した主キーを持つモデルを返します。コレクションに合うモデルがなければ、Illuminate\Database\Eloquent\ModelNotFoundException を投げます。
$users = User::all();
$user = $users->findOrFail(1);
fresh#
fresh は、コレクションの全部のモデルを、データベースから取り直します。決めたリレーションは、先読み(eager load。使うときに1件ずつ読むのではなく、先にまとめて読んでおくこと)もされます。
$users = $users->fresh();
$users = $users->fresh('comments');
intersect#
intersect は、渡したコレクションにもあるモデルを全部返します。
use App\Models\User;
$users = $users->intersect(User::whereIn('id', [1, 2, 3])->get());
load#
load は、決めたリレーションを、コレクションの全部のモデルに、先読みします。
$users->load(['comments', 'posts']);
$users->load('comments.author');
$users->load(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);
loadMissing#
loadMissing は、決めたリレーションのうち、まだ読み込んでいないものだけを、全部のモデルに先読みします。
$users->loadMissing(['comments', 'posts']);
$users->loadMissing('comments.author');
$users->loadMissing(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);
modelKeys#
modelKeys は、コレクションの全部のモデルの主キーを返します。
$users->modelKeys();
// [1, 2, 3, 4, 5]
makeVisible#
makeVisible は、ふだんは「隠れている」属性を、コレクションの各モデルで、見えるようにします。
$users = $users->makeVisible(['address', 'phone_number']);
makeHidden#
makeHidden は、ふだんは「見える」属性を、コレクションの各モデルで、隠します。
$users = $users->makeHidden(['address', 'phone_number']);
mergeVisible#
mergeVisible は、いま見える属性は残したまま、見える属性を足します。
$users = $users->mergeVisible(['middle_name']);
mergeHidden#
mergeHidden は、いま隠れている属性は残したまま、隠す属性を足します。
$users = $users->mergeHidden(['last_login_at']);
only#
only は、渡した主キーを持つモデルだけを全部返します。
$users = $users->only([1, 2, 3]);
partition#
partition は、条件でモデルを2つに分けます。Illuminate\Support\Collection が返り、その中に、Illuminate\Database\Eloquent\Collection が2つ入っています。
$partition = $users->partition(fn ($user) => $user->age > 18);
dump($partition::class); // Illuminate\Support\Collection
dump($partition[0]::class); // Illuminate\Database\Eloquent\Collection
dump($partition[1]::class); // Illuminate\Database\Eloquent\Collection
setAppends#
setAppends は、コレクションの各モデルの追加する属性を、全部、一時的に置き換えます。
$users = $users->setAppends(['is_admin']);
setVisible#
setVisible は、コレクションの各モデルの見える属性を、全部、一時的に置き換えます。
$users = $users->setVisible(['id', 'name']);
setHidden#
setHidden は、コレクションの各モデルの隠す属性を、全部、一時的に置き換えます。
$users = $users->setHidden(['email', 'password', 'remember_token']);
toQuery#
toQuery は、Eloquent の問い合わせを返します。この問い合わせには、コレクションに入っているモデルの主キーで絞る whereIn の条件が付いています。
use App\Models\User;
$users = User::where('status', 'VIP')->get();
$users->toQuery()->update([
'status' => 'Administrator',
]);
unique#
unique は、重なりのないモデルだけを返します。コレクションの中に、同じ主キーのモデルがあれば、取り除かれます。
$users = $users->unique();
withoutAppends#
withoutAppends は、コレクションの各モデルの追加する属性を、全部、一時的に取り除きます。
$users = $users->withoutAppends();
自分専用のコレクション#
あるモデルで、自分で作った Collection を使いたいときは、モデルに CollectedBy 属性(PHP の属性。クラスの前に書く印)を付けます。
<?php
namespace App\Models;
use App\Support\UserCollection;
use Illuminate\Database\Eloquent\Attributes\CollectedBy;
use Illuminate\Database\Eloquent\Model;
#[CollectedBy(UserCollection::class)]
class User extends Model
{
// ...
}
別のやり方として、モデルに newCollection メソッドを書けます。
<?php
namespace App\Models;
use App\Support\UserCollection;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Create a new Eloquent Collection instance.
*
* @param array<int, \Illuminate\Database\Eloquent\Model> $models
* @return \Illuminate\Database\Eloquent\Collection<int, \Illuminate\Database\Eloquent\Model>
*/
public function newCollection(array $models = []): Collection
{
$collection = new UserCollection($models);
if (Model::isAutomaticallyEagerLoadingRelationships()) {
$collection->withRelationshipAutoloading();
}
return $collection;
}
}
newCollection を書くか、CollectedBy 属性を付けておきます。すると、ふだんなら Illuminate\Database\Eloquent\Collection が返る場面で、いつも自分のコレクションが返ります。
アプリの全部のモデルで、自分のコレクションを使いたいときは、全部のモデルが受け継ぐ、基本のモデルのクラスに、newCollection を書きます。
関連するページ#
公式ドキュメント(英語)
2026年10月5日時点の内容をもとに、日本語でまとめています。