I'm currently using Laravel 9. I need help refactoring a query that I have created. I eager load a relationship users
here:
$items = Item::where('type', 'user')->with('users')->get();
Which brings me back a collection of Items with the associated Users. What I would love is a unique list of all of the associated Users, but I'm struggling to figure out how I do it through a query, or maybe a function map.
This is what I have tried to get the list I want, but it feels like a lot of code, and I imagine there is a much better way of doing this.
$items = Item::where('type', 'user')->with('users')->get();
$users = new Collection();
foreach ($items as $item) {
$itemUsers = $item->users()->get();
$users = $users->merge($itemUsers);
}
$uniqueUsers = $users->unique();
Does anyone have any ideas of how I could improve this please, without iterating over the $items
in a foreach?
CodePudding user response:
Instead of querying from the Item
model, start your query from the User
model, and constrain them to only those that have an associated Item
with type
of user
:
$users = User::whereHas('items', function ($subQuery) {
return $subQuery->where('items.type', 'user');
})->get();
This requires having the inverse of the relationship defined on your User
model. You currently have public function users()
in your Item
model, you should also have public function item()
(or public function items()
) in your User
mode. Adjust the code as required (i.e. whereHas('items')
or whereHas('item')
).