Laravel查询生成器where()用于产品必须有多个标签(使用product_tags数据透视表多对多)



我是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
);

这个工作完美,但我有一个问题,当它翻译成一个雄辩的查询生成器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不熟悉。

假设我有一个表mealstags,meals_tags连接它们(多对多)。


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

$parameters['tags']的类型是string,用逗号分隔数字(正integers大于0),这样我就可以选择在需要的地方爆炸它。

假设您已经在Meal模型上定义了belongsToMany(多对多)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();

相关内容

最新更新