Laravel Eloquent 查找具有所有给定标签的帖子

问题描述

考虑如下 3 个表

class Post extends Model
{
    public function tags()
    {
        return $this->belongsToMany(Tag::class,'post_tags','post_id','tag_id');
    }

}

posts

|id | title   |
+---+---------+
|1  |  post1  |
|2  |  post2  |
|3  |  post3  |
|4  |  post4  |

tags

|id |  value  |
+---+---------+
|1  |  tag01  |
|2  |  tag02  |
|3  |  tag03  |
|4  |  tag04  |

post_tags

|  post_id | tag_id  |
+----------+---------+
|     1    |    1    |
|     2    |    3    |
|     2    |    4    |
|     3    |    1    |
|     4    |    1    |
|     4    |    4    |

唯一同时包含 tag01tag04 的帖子是带有 id = 4 的帖子

但是当我使用此代码获得 posts

Post::whereHas('tags',function($q) {
  $q->whereIn('tag_id',[1,4]);
}

我收到所有包含 tag01tag04 的帖子。

我想在 Posttag01tag02 关系中得到 tags

如何使用 Eloquent 或如果无法使用 QueryBuilder 实现此结果

解决方法

我认为你可以使用多个 where 条件

 Post::whereHas('tags',function($q) {
       $q->where('tag_id',1);
   
    })->whereHas('tags',4);
   
    })->get();

如果 id 是动态的,那么

$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();
,

whereHas 方法接受更多参数,其中之一是计数:

Post::whereHas('tags',fn ($q) => $q->whereIn('tag_id',$tags),'=',count($tags))->get();

如果您正在寻找 [1,4] 这就是说找到我所有带有标签 14 的帖子,然后只选择恰好包含其中 2 个标签的帖子( count),这意味着找到所有具有所有这些标签的帖子。

Laravel 8.x Docs - Eloquent - Relationships - Querying Relationship Existence whereHas