Considere 3 tablas como se muestra a continuación
class Post extends Model { public function tags() { return $this->belongsToMany(Tag::class, 'post_tags', 'post_id', 'tag_id'); } } tabla de posts
|id | title | +---+---------+ |1 | post1 | |2 | post2 | |3 | post3 | |4 | post4 | tabla de tags
|id | value | +---+---------+ |1 | tag01 | |2 | tag02 | |3 | tag03 | |4 | tag04 | tabla post_tags
| post_id | tag_id | +----------+---------+ | 1 | 1 | | 2 | 3 | | 2 | 4 | | 3 | 1 | | 4 | 1 | | 4 | 4 | La única publicación que tiene tag01 y tag04 es la publicación con id = 4
Pero cuando recibo posts con este código
Post::whereHas('tags', function($q) { $q->whereIn('tag_id', [1, 4]); } Obtengo todas las publicaciones que tienen tag01 o tag04 .
Quiero obtener Post donde tengan tanto tag01 como tag02 en su relación de tags .
¿Cómo puedo lograr este resultado usando Eloquent o si no es posible usando QueryBuilder
Creo que puedes usar múltiples condiciones where
Post::whereHas('tags', function($q) { $q->where('tag_id', 1); })->whereHas('tags', function($q) { $q->where('tag_id', 4); })->get();si los identificadores son dinámicos, entonces
$id=[1,4]; Post::where(function($query)use($id){ foreach ($id as $value){ $query->whereHas('tags',function ($query)use($value){ $query->where('tag_id',$value); }); } })->get();El método whereHas toma más argumentos y uno de ellos es un conteo:
Post::whereHas('tags', fn ($q) => $q->whereIn('tag_id', $tags), '=', count($tags))->get(); Si está buscando [1, 4] lo que esto significa es encontrar todas las publicaciones que tengan las etiquetas 1 o 4 , pero luego elija solo las que tengan exactamente 2 de estas (el conteo), lo que significa encontrar todas las publicaciones que tengan todas estas etiquetas.
Laravel 8.x Docs - Eloquent - Relaciones - Consultando la existencia de relaciones whereHas