You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel关联查询中如何使用whereHas实现多流派AND条件筛选动画作品

解决方案

问题根源

你当前写法中的whereHas搭配whereIn,仅判断动画关联的流派是否存在任意一个在选中列表内,自然是OR逻辑,无法满足同时匹配所有选中流派的需求。

最优修改方案

直接利用Laravel whereHas 方法的计数参数即可实现需求,仅需要修改流派筛选部分的逻辑:

if($request->genres){
    // 先对传入的流派ID去重,避免重复值导致计数错误
    $genres = array_unique($request->genres ?? []);
    if (!empty($genres)) {
        $anime->whereHas('genres', function($q) use($genres){
            $q->whereIn('id', $genres);
        }, '=', count($genres));
    }
}

逻辑说明

whereHas 第三个和第四个参数的作用是:要求关联表中符合条件的记录数量等于传入的选中流派总数。也就是说如果用户选了3个流派,那么该动画的关联流派中必须同时存在这3个,满足条件的关联记录数才会等于3,符合筛选要求,完美实现AND逻辑。

兼容备选方案

如果使用的Laravel版本过低不支持上述计数参数,也可以通过循环叠加whereHas实现,只是选中流派较多时性能略低于上面的方案:

if($request->genres){
    $genres = array_unique($request->genres ?? []);
    foreach ($genres as $genreId) {
        $anime->whereHas('genres', function($q) use ($genreId) {
            $q->where('id', $genreId);
        });
    }
}

完整修改后代码

$anime = AnimeShow::select('id', 'slug', 'status', 'title_eng', 'title_jap', 'description', 'episodes', 'premier_date', 'status')
        ->with('media:anime_show_id,image_path');

if($request->genres){
    $genres = array_unique($request->genres ?? []);
    if (!empty($genres)) {
        $anime->whereHas('genres', function($q) use($genres){
            $q->whereIn('id', $genres);
        }, '=', count($genres));
    }
}

if($request->airing){
    $anime->whereIn('status', $request->airing);
}

$anime->search($request->search);
        
return response($anime->paginate($request->perPage, ['*'], 'page', $request->currentPage));

内容的提问来源于stack exchange,提问作者Beusebiu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 07:36:03