Eloquent:コレクション
イントロダクション
複数のモデル結果を返すEloquentのメソッドはすべて、getメソッドやリレーションを介してアクセスした結果を含め、Illuminate\Database\Eloquent\Collectionクラスのインスタンスを返します。EloquentコレクションオブジェクトはLaravelのベースコレクションを拡張しているため、Eloquentモデルの配列を流暢に操作するために使用する多くのメソッドを自然に継承しています。これらの便利なメソッドのすべてを学ぶために、Laravelコレクションのドキュメントを必ず確認してください!
すべてのコレクションはイテレータとしても機能するため、単純なPHP配列のようにループ処理できます。
1use App\Models\User;2 3$users = User::where('active', 1)->get();4 5foreach ($users as $user) {6 echo $user->name;7}
しかし、前述したように、コレクションは配列よりもはるかに強力で、直感的なインターフェイスを使用してチェーンできるさまざまなmap/reduce操作を公開しています。たとえば、すべてのアクティブでないモデルを削除し、残りの各ユーザーのファーストネームを収集できます。
1$names = User::all()->reject(function (User $user) {2 return $user->active === false;3})->map(function (User $user) {4 return $user->name;5});
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 contains diff except find findOrFail fresh intersect load loadMissing modelKeys makeVisible makeHidden only setVisible setHidden toQuery unique
append($attributes)
appendメソッドは、コレクション内のすべてのモデルに対して属性を追加すべきであることを示すために使用します。このメソッドは、属性の配列または単一の属性を引数に取ります。
1$users->append('team');2 3$users->append(['team', 'is_admin']);
contains($key, $operator = null, $value = null)
containsメソッドは、指定したモデルインスタンスがコレクションに含まれているかどうかを判断するために使用します。このメソッドは、主キーまたはモデルインスタンスを引数に取ります。
1$users->contains(1);2 3$users->contains(User::find(1));
diff($items)
diffメソッドは、指定したコレクションに存在しないすべてのモデルを返します。
1use App\Models\User;2 3$users = $users->diff(User::whereIn('id', [1, 2, 3])->get());
except($keys)
exceptメソッドは、指定した主キーを持たないすべてのモデルを返します。
1$users = $users->except([1, 2, 3]);
find($key)
findメソッドは、指定したキーに一致する主キーを持つモデルを返します。$keyがモデルインスタンスの場合、findは主キーに一致するモデルを返そうとします。$keyがキーの配列である場合、findは指定した配列内に主キーを持つすべてのモデルを返します。
1$users = User::all();2 3$user = $users->find(1);
findOrFail($key)
findOrFailメソッドは、指定したキーに一致する主キーを持つモデルを返すか、コレクション内に一致するモデルが見つからない場合はIlluminate\Database\Eloquent\ModelNotFoundException例外を投げます。
1$users = User::all();2 3$user = $users->findOrFail(1);
fresh($with = [])
freshメソッドは、コレクション内の各モデルの新しいインスタンスをデータベースから取得します。さらに、指定したリレーションはEagerロードされます。
1$users = $users->fresh();2 3$users = $users->fresh('comments');
intersect($items)
intersectメソッドは、指定したコレクションにも存在するすべてのモデルを返します。
1use App\Models\User;2 3$users = $users->intersect(User::whereIn('id', [1, 2, 3])->get());
load($relations)
loadメソッドは、コレクション内のすべてのモデルに対して、指定したリレーションをEagerロードします。
1$users->load(['comments', 'posts']);2 3$users->load('comments.author');4 5$users->load(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);
loadMissing($relations)
loadMissingメソッドは、リレーションがまだロードされていない場合に、コレクション内のすべてのモデルに対して、指定したリレーションをEagerロードします。
1$users->loadMissing(['comments', 'posts']);2 3$users->loadMissing('comments.author');4 5$users->loadMissing(['comments', 'posts' => fn ($query) => $query->where('active', 1)]);
modelKeys()
modelKeysメソッドは、コレクション内のすべてのモデルの主キーを返します。
1$users->modelKeys();2 3// [1, 2, 3, 4, 5]
makeVisible($attributes)
makeVisibleメソッドは、コレクション内の各モデルで通常は「非表示」になっている属性を表示します。
1$users = $users->makeVisible(['address', 'phone_number']);
makeHidden($attributes)
makeHiddenメソッドは、コレクション内の各モデルで通常は「表示」されている属性を非表示にします。
1$users = $users->makeHidden(['address', 'phone_number']);
only($keys)
onlyメソッドは、指定した主キーを持つすべてのモデルを返します。
1$users = $users->only([1, 2, 3]);
setVisible($attributes)
setVisibleメソッドは、コレクション内の各モデルの表示属性をすべて一時的に上書きします。
1$users = $users->setVisible(['id', 'name']);
setHidden($attributes)
setHiddenメソッドは、コレクション内の各モデルの非表示属性をすべて一時的に上書きします。
1$users = $users->setHidden(['email', 'password', 'remember_token']);
toQuery()
toQueryメソッドは、コレクションモデルの主キーに対するwhereIn制約を含むEloquentクエリビルダインスタンスを返します。
1use App\Models\User;2 3$users = User::where('status', 'VIP')->get();4 5$users->toQuery()->update([6 'status' => 'Administrator',7]);
unique($key = null, $strict = false)
uniqueメソッドは、コレクション内の一意のモデルをすべて返します。コレクション内の他のモデルと同じ主キーを持つモデルは削除されます。
1$users = $users->unique();
カスタムコレクション
特定のモデルとやり取りする際にカスタムCollectionオブジェクトを使用したい場合は、モデルにCollectedByアトリビュートを追加します。
1<?php 2 3namespace App\Models; 4 5use App\Support\UserCollection; 6use Illuminate\Database\Eloquent\Attributes\CollectedBy; 7use Illuminate\Database\Eloquent\Model; 8 9#[CollectedBy(UserCollection::class)]10class User extends Model11{12 // ...13}
または、モデルにnewCollectionメソッドを定義することもできます。
1<?php 2 3namespace App\Models; 4 5use App\Support\UserCollection; 6use Illuminate\Database\Eloquent\Collection; 7use Illuminate\Database\Eloquent\Model; 8 9class User extends Model10{11 /**12 * Create a new Eloquent Collection instance.13 *14 * @param array<int, \Illuminate\Database\Eloquent\Model> $models15 * @return \Illuminate\Database\Eloquent\Collection<int, \Illuminate\Database\Eloquent\Model>16 */17 public function newCollection(array $models = []): Collection18 {19 return new UserCollection($models);20 }21}
newCollectionメソッドを定義するか、モデルにCollectedByアトリビュートを追加すると、Eloquentが通常Illuminate\Database\Eloquent\Collectionインスタンスを返すときはいつでも、カスタムコレクションのインスタンスを受け取れます。
アプリケーションのすべてのモデルでカスタムコレクションを使用したい場合は、アプリケーションのすべてのモデルが拡張するベースモデルクラスでnewCollectionメソッドを定義する必要があります。