Laravel 查询生成器 where() 用于当产品必须具有多个标签时(使用 product_tags pivot table 多对多)

Laravel Query builder where() for when Product has to have multiple tags (with product_tags pivot table many-to-many)

我是 Laravel 的新手,我需要构建一个复杂的查询。我设法对它进行了排序,除非用户要求多个标签 (tags = 1, 2, 3)。显示的产品必须包含用户要求的所有 tags(不仅是一两个,而是全部)。

我在SQL中有查询(这个例子是两个标签,我会根据传递的标签数量将其切换为不同的数字):

SELECT  m.*
FROM  meals m
WHERE EXISTS (
    SELECT 1
    FROM meals_tags t
    WHERE m.id = t.meals_id AND
        t.tags_id IN (227,25)
    HAVING COUNT(1) = 2
);

这个工作得很好,但是我在将它转换为 Eloquent 查询生成器 where 方法时遇到了问题。

我在同一个查询中包含另一个 where 方法,所以我也想附加这个方法。

我试过这个:

DB::table('meals')
    ->select('id')
    ->where(function ($query) use ($parameters) {
        if (isset($parameters['tags'])) {
            $array = explode(',', $parameters['tags']);
            $query->select(DB::raw(1))
                ->from('meals_tags')
                ->where('meals.id', '=', 'meals_tags.meals_id')
                ->whereIn('meals_tags.tags_id', $array)
                ->having(DB::raw('COUNT(1)'), '=', count($parameters['tags']));
        }
    });

可是我找不到办法。 Laravel 和 PHP.

的新手

假设我有 table mealstagsmeals_tags 连接它们(多对多)。


$paramaters 来自 GET (...?tags=1,2,3&lang=en&another=something...),它们是键值对数组 (['tags' => '1,2,3', 'lang' => 'en'])

$parameters['tags']string 类型,带有逗号分隔的数字(正数 integers 大于 0),因此如果某处需要,我可以选择展开它。

假设你在Meal模型上定义了belongsToMany(Many-to-Many)meal_tags关系,你可以试试

Meal::select('id')
    ->when(
        $request->has('tags'),
        function($query) use ($request) {
            $requestedTagIds = explode(',', $request->tags);

            return $query->whereHas(
                'meal_tags', 
                fn ($query) => $query->whereIn('tags_id', $requestedTagIds),
                '=', 
                count($requestedTagIds)
            );
        }
    )
    ->get();