I need to make a query to find a Model that has an exact set of a many-to-many relationship.
For example, I have a Blog post that has many Tags. The tags can belongs to many blog posts.
How could I retrieve all blogs posts that have the tag #1, #2 and #3 without any other tag, only these 3, in an efficient manner?
CodePudding user response:
First approach that comes to my mind is a ->whereHas()
for each Tag you want to find, something like:
$tagIds = [1, 2, 3];
$query = Blog::where(function ($query) use ($tagIds) {
foreach ($tagIds as $tagId) {
$query->whereHas('tags', function ($subQuery) use ($tagId) {
return $subQuery->where('tags.id', $tagId);
});
}
})->has('tags', '=', count($tagIds));
// Additional Clauses/Filters/Etc.
$blogs = $query->get();
This will execute an additional query for the Tags supplied (based on ID), and filter your Blog
records to only those that match all supplied Tags.