Laravel Eloquent嵌套whereHas返回所有关联产品问题如何解决?
问题根因
现有代码中的whereHas仅用于过滤「至少存在一个关联了id=21的feature的产品的分类」,该筛选逻辑不会作用于with预加载的关联数据,因此即便分类满足筛选条件,预加载时依然会返回该分类下的所有产品。
解决方案
将产品的feature筛选条件同时应用到whereHas和预加载的products关联上,可将筛选逻辑封装为闭包避免重复代码。
基础实现(返回符合条件的产品+产品的所有关联feature)
$featureId = 21; // 封装产品筛选闭包 $productFilter = function ($query) use ($featureId) { $query->whereHas('features', function ($query2) use ($featureId) { $query2->where('id', $featureId); })->select('id', 'title'); }; $category = Category::whereHas('products', $productFilter) ->where('slug', 'category-slug') ->with([ 'products' => $productFilter, 'products.features' ]) ->first(); // slug为唯一值时用first替代get,直接返回分类实例而非集合
进阶实现(返回符合条件的产品+仅返回匹配的id=21的feature)
如果不需要返回产品的所有feature,仅需要保留id=21的那条feature记录,可对嵌套关联也增加筛选:
$featureId = 21; $productFilter = function ($query) use ($featureId) { $query->whereHas('features', fn($q) => $q->where('id', $featureId)) ->select('id', 'title'); }; // 封装feature筛选闭包 $featureFilter = fn($query) => $query->where('id', $featureId); $category = Category::whereHas('products', $productFilter) ->where('slug', 'category-slug') ->with([ 'products' => $productFilter, 'products.features' => $featureFilter ]) ->first();
内容的提问来源于stack exchange,提问作者K1-Aria
相关产品推荐
相关产品推荐

