Question

Let's say you have an Illuminate Collection of User model objects.

$users = User::all();

Now, you want to get a single user from that collection by ID.

The only way I knew of doing this (super ugly):

$user_id = 22;
$user = $users->filter(function($user) use ($user_id) {
    return $user->id = $user_id;
})->first();

(Taken from this question and answer.)

However, if you do this, the $users collection is destroyed and unusable. For instance, if there were 100 unique users in the collection before, you will instead now have 100 copies of the user with id 22 for some God forsaken reason.

How can I get a single user by ID from the collection without destroying the collection or looping through it?

I thought this would work...

$user_id = 22;
$temp_users = $users;
$user = $temp_users->filter(function($user) use ($user_id) {
    return $user->id = $user_id;
})->first();

But, even more infuriatingly, $users is still destroyed by the filter call - so evidently $temp_users = $users is identical to $temp_users = &$users or something. There appears to be no way of duplicating a collection.

According to this Github issue, Collection::filter() used to return brand new object instances. Evidently, it doesn't anymore. And neither does $temp_users = $users; I guess - which is confusing as hell.

Was it helpful?

Solution

Eloquent responses in the form of collections actually extend a special collection type located at Illuminate\Database\Eloquent\Collection, which has a familiar method find(). Simply use that.

$users = User::all();

$jack = $users->find(22);

OTHER TIPS

In case ID is not your primary key, you could use firstWhere() like this:

$user_id = 22;
$userYouNeed = $users->firstWhere('id', $user_id);

If you would have a more complex condition you can consider using first() and providing your own callback with a condition like this

$user_id = 22;
$userYouNeed = $users->firs(function ($user) use ($user_id) {
    return $user->id === $user_id; // Or a more complex condition
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top