John Davidson

php - Laravel filtering a hasMany relation

0 comments
Message:


Background first on my question. A user hasMany contacts and a contact hasMany anniversaries. I want to filter the upcoming anniversaries. So far I have this:


$filtered = auth()->user()->contacts()->get()->each(function ($contact) {
$contact->anniversaries->filter(function ($anniversary) {

// return true or false based on a method on the anniversary model
return $anniversary->method() == true;

});
});

But this just returns all the contacts (obviously) with all their anniversaries, and I wish to exclude the ones that are false when calling the $anniversary->method().


Whatever is in the $anniversary->method() is not important, this just returns a true or false.


When I do the following, it works:


$collection = auth()->user()->anniversaries()->get();

$filtered = $collection->filter(function ($anniversary) {
return $anniversary->method() == true;
});

I get only the anniversaries from where the $anniversary->method() is indeed true.


My question is mainly, why does this happen, I only want to understand it, not so much need an answer on how to make it work. Thanks in advance for any insights!



My Answer:
>user()->contacts->flatMap(function ($contact) {
return $contact->anniversaries->filter(function ($anniversary) {
return $anniversary->date >= now();
});
});

This code will retrieve all contacts of the authenticated user, then flatMap through each contact to retrieve all anniversaries. Finally, it will filter out only the upcoming anniversaries based on the date.

You can further optimize this code by eager loading the contacts and anniversaries to reduce the number of database queries:

$filtered = auth()->user()->contacts()->with('anniversaries')->get()->flatMap(function ($contact) {
return $contact->anniversaries->filter(function ($anniversary) {
return $anniversary->date >= now();
});
});

This code will eager load all contacts and their anniversaries in a single query, then filter out the upcoming anniversaries.

Rate this post

3 of 5 based on 3684 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us