Laravel/Eloquent回调内循环生成多where条件实现关联全匹配筛选问题
问题原因
你之前的两种写法逻辑都有问题:
- 第一种写法的
where('slug', $featureSlugs)实际等价于whereIn('slug', $featureSlugs),匹配规则是只要交易所存在任意一个符合要求的功能就会被筛选出来,不是同时拥有全部功能,所以功能选多了就会不符合预期。 - 第二种写法在同一个关联查询里循环加
where,相当于要求单个功能记录的slug同时等于多个不同的值,逻辑上不可能成立,因此查不到结果。
正确实现方案
方案1(推荐,性能更优)
利用whereHas的计数参数限制匹配的关联数量,只要匹配到的功能数等于你传入的slug数组长度,就说明该交易所拥有全部选中的功能:
$featureSlugs = ['security', 'mobile-app', '2FA']; $exchanges = Exchange::whereHas('features', function ($q) use ($featureSlugs) { // 先筛选出所有匹配选中slug的关联记录 $q->whereIn('slug', $featureSlugs); // 要求匹配到的关联数量等于选中的功能总数 }, '=', count($featureSlugs))->get();
方案2(嵌套whereHas写法)
如果你的业务场景允许功能slug重复,可以用嵌套whereHas的写法,每个slug单独做一次关联校验:
$featureSlugs = ['security', 'mobile-app', '2FA']; $query = Exchange::query(); foreach ($featureSlugs as $featureSlug) { $query->whereHas('features', function ($q) use ($featureSlug) { $q->where('slug', $featureSlug); }); } $exchanges = $query->get();
内容的提问来源于stack exchange,提问作者Barry Deen
相关产品推荐
相关产品推荐

