イントロダクション
get
メソッドで取得した結果や、リレーションによりアクセスした結果など、結果として複数のモデルを返すEloquentメソッドはすべて、Illuminate\Database\Eloquent\Collection
クラスのインスタンスを返します。EloquentコレクションオブジェクトはLaravelの基本的なコレクションを拡張しているため、基になるEloquentモデルの配列をスムーズに操作できるように使用する、数十のメソッドを自然に継承します。これらの便利なメソッドをすべて学ぶために、Laravelコレクションのドキュメントは必ず確認してください!
すべてのコレクションはイテレーターとしても機能し、単純なPHP配列のようにループで使えます。
use App\Models\User;
$users = User::where('active', 1)->get();
foreach ($users as $user) {
echo $user->name;
}
ただし、前述のようにコレクションは配列よりもはるかに強力であり、直感的なインターフェイスを使用してチェーンする可能性を持つさまざまなマップ/リデュース操作を用意しています。たとえば、非アクティブなモデルをすべて削除してから、残りのユーザーの名を収集する場面を考えましょう。
$names = User::all()->reject(function (User $user) {
return $user->active === false;
})->map(function (User $user) {
return $user->name;
});
Eloquentコレクションの変換
ほとんどのEloquentコレクションメソッドはEloquentコレクションの新しいインスタンスを返しますが、collapse
、flatten
、flip
、keys
、pluck
、zip
メソッドは、基本のコレクションインスタンスを返します。同様に、map
操作がEloquentモデルを含まないコレクションを返す場合、それは基本コレクションインスタンスに変換されます。
利用可能なメソッド
すべてのEloquentコレクションはベースのLaravelコレクションオブジェクトを拡張します。したがって、これらは基本コレクションクラスによって提供されるすべての強力なメソッドを継承します。
さらに、Illuminate\Database\Eloquent\Collection
クラスは、モデルコレクションの管理を支援するメソッドのスーパーセットを提供します。ほとんどのメソッドはIlluminate\Database\Eloquent\Collection
インスタンスを返します。ただし、modelKeys
などの一部のメソッドは、Illuminate\Support\Collection
インスタンスを返します。
append($attributes)
append
メソッドは、コレクション内の全モデルへ属性を追加するように指示するために使用します。このメソッドには、属性の配列か、単一の属性を指定します。
$users->append('team');
$users->append(['team', 'is_admin']);
contains($key, $operator = null, $value = null)
contains
メソッドを使い、指定モデルインスタンスがコレクションに含まれているかどうかを判定できます。このメソッドは、主キーまたはモデルインスタンスを引数に取ります。
$users->contains(1);
$users->contains(User::find(1));
diff($items)
diff
メソッドは、指定コレクションに存在しないすべてのモデルを返します。
use App\Models\User;
$users = $users->diff(User::whereIn('id', [1, 2, 3])->get());
except($keys)
except
メソッドは、指定する主キーを持たないすべてのモデルを返します。
$users = $users->except([1, 2, 3]);
find($key)
find
メソッドは、指定キーと一致する主キーを持つモデルを返します。$key
がモデルインスタンスの場合、find
は主キーに一致するモデルを返そうとします。$key
がキーの配列である場合、find
は指定配列の中の主キーを持つすべてのモデルを返します。
$users = User::all();
$user = $users->find(1);
fresh($with = [])
fresh
メソッドは、データベースからコレクション内の各モデルの新しいインスタンスを取得します。さらに、指定したリレーションはすべてEagerロードされます。
$users = $users->fresh();
$users = $users->fresh('comments');
intersect($items)
intersect
メソッドは、指定コレクションにも存在するすべてのモデルを返します。
use App\Models\User;
$users = $users->intersect(User::whereIn('id', [1, 2, 3])->get());
load($relations)
load
メソッドは、コレクション内のすべてのモデルに対して指定するリレーションをEagerロードします。
$users->load(['comments', 'posts']);
$users->load('comments.author');
$users->load(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);
loadMissing($relations)
loadMissing
メソッドは、関係がまだロードされていない場合、コレクション内のすべてのモデルに対して指定するリレーションをEagerロードします。
$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($attributes)
makeVisible
メソッドは、通常コレクション内の各モデルで"hidden"になっている属性をvisibleにします。
$users = $users->makeVisible(['address', 'phone_number']);
makeHidden($attributes)
makeHidden
メソッドは、通常コレクション内の各モデルで"visible"になっている属性をhiddenにします。
$users = $users->makeHidden(['address', 'phone_number']);
only($keys)
only
メソッドは、指定主キーを持つすべてのモデルを返します。
$users = $users->only([1, 2, 3]);
setVisible($attributes)
setVisible
メソッドは、コレクション内の各モデルの全てのvisible属性を一時的に上書きします。
$users = $users->setVisible(['id', 'name']);
setHidden($attributes)
setHidden
メソッドは、コレクション内の各モデルの全てのhidden属性を一時的に上書きします。
$users = $users->setHidden(['email', 'password', 'remember_token']);
toQuery()
toQuery
メソッドは、コレクションモデルの主キーに対するwhereIn
制約を含むEloquentクエリビルダインスタンスを返します。
use App\Models\User;
$users = User::where('status', 'VIP')->get();
$users->toQuery()->update([
'status' => 'Administrator',
]);
unique($key = null, $strict = false)
unique
メソッドは、コレクション内のすべての一意のモデルを返します。コレクション内の、同じタイプで同じ主キーを持つモデルをすべて削除します。
$users = $users->unique();
カスタムコレクション
特定のモデルを操作するときにカスタムのCollection
オブジェクトを使用したい場合は、モデルでnewCollection
メソッドを定義します。
<?php
namespace App\Models;
use App\Support\UserCollection;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 新しいEloquentCollectionインスタンスの作成
*
* @param array<int, \Illuminate\Database\Eloquent\Model> $models
* @return \Illuminate\Database\Eloquent\Collection<int, \Illuminate\Database\Eloquent\Model>
*/
public function newCollection(array $models = []): Collection
{
return new UserCollection($models);
}
}
newCollection
メソッドを一度定義したら、Eloquentが通常Illuminate\Database\Eloquent\Collection
インスタンスを返すときは、いつでもカスタムコレクションのインスタンスを受け取ります。アプリケーションのすべてのモデルにカスタムコレクションを使用する場合は、アプリケーションのすべてのモデルによって拡張される基本モデルクラスでnewCollection
メソッドを定義する必要があります。