Laravel 查询多对多关系

Laravel query on Many to Many relationship

我有一个 API 来跟踪照片和标签。每张照片可以有 N 个标签,一个标签可以链接到 N 张照片。这是使用 3 tables:

完成的

现在我正在努力让所有照片都用一组标签标记,我的想法是用标签列表向我的 API 发出请求,并获得至少包含所有标签。

我一直在尝试使用 whereIn 运算符。

这是我的代码(现在都是硬编码):

$photos = Photo::whereHas('tags', function (Builder $query) {
            $query->whereIn('tag', ['a5', 'mate', 'Brillante']);
        })->get();

        return response()->json($photos, 200);

当我执行它时 return 所有匹配一个标签的照片,我只需要具有所有请求标签的照片(在本例中为 a5,伙伴)。

我正在研究 Laravel 9。

编辑:

正如 Tim Lewis 所建议的那样,我尝试了循环:

$tags = array("a5", "mate", "Brilante");
        $photoQuery = Photo::query();

        foreach($tags as $tag) {
            \Log::debug($tag);
            $photoQuery->whereHas('tags', function($query) use ($tag) {
                return $query->where('tag', $tag);
            });
        }

        $photos = $photoQuery->get();

现在 return 我认为这是一个空列表,因为正在寻找只有我在数组上硬编码的 3 个标签的照片。

编辑 2:

似乎这些更改是正确的,但出于某种原因,Postman 没有向我显示这些更改的任何结果是我的问题的解决方案。

由于 whereIn() 方法匹配提供的值中的 any,而不是 all,您需要修改这个。指定多个 whereHas() 子句,每个标签 1 个,应该有效:

$photoQuery = Photo::query();
foreach ($request->input('tags') as $tag) {
  $photoQuery = $photoQuery->whereHas('tags', function ($query) use ($tag) {
    return $query->where('tag', $tag);
  });
}
$photos = $photoQuery->get();

现在,根据发送到您的 API 的 tags(假设通过 $request 变量作为 'tags' => [] 数组),此查询将包含 whereHas() 每个标签的子句,并且只有 return Photo 个具有所有指定标签的记录。