Reputation:
I currently have 2 methods which carry out search queries both ways then they are merged together to retrieve the result.
public function linkedTo() {
return $this->hasMany(Linked::class, 'team_id');
}
public function linkedFrom() {
return $this->hasMany(Linked::class, 'linked_id');
}
Query
$linkedTo = $team->linkedTo()->with(['games' => function ($query) use ($search) {
$query->where('title', 'like', "%$search%");
}])->get();
$linkedFrom = $team->linkedFrom()->with(['games' => function ($query) use ($search) {
$query->where('title', 'like', "%$search%");
}])->get();
$links = $linkedTo->merge($linkedFrom);
To get the result I need from the search results I had to merge these together.
Is there a cleaner way to join these together within one query?
Upvotes: 0
Views: 63
Reputation: 40683
If you want to reduce code duplication (but not actually change what is executed) you can do this:
$filter = function ($query) use ($search) {
$query->where('title', 'like', "%$search%");
};
$linkedTo = $team->linkedTo()->with(['games' => $filter ])->get();
$linkedFrom = $team->linkedFrom()->with(['games' => $filter ])->get();
$links = $linkedTo->merge($linkedFrom);
Upvotes: 0
Reputation: 1621
Use union
:
// First build the queries, note I removed 'get()'
$linkedTo = $team->linkedTo()->with(['games' => function ($query) use ($search) {
$query->where('title', 'like', "%$search%");
}]);
$linkedFrom = $team->linkedFrom()->with(['games' => function ($query) use ($search) {
$query->where('title', 'like', "%$search%");
}]);
// Now union and get the results
$links = $linkedTo->union($linkedFrom)->get();
More details here: https://laravel.com/docs/8.x/queries#unions
Upvotes: 1