Laravel 9嵌套hasManyThrough关系使用withCount报错问题排查
Laravel 9中hasManyThrough关联的嵌套关联统计问题
我在Laravel 9里用hasManyThrough关联了PingtreeGroup到Pingtree(通过PingtreeEntry),现在想统计关联的pingtrees下的tiers总数,用with('pingtrees.tiers')没问题,但加了withCount('pingtrees.tiers')就报错:
Call to undefined method App\Models\PingtreeGroup::pingtrees.tiers()
相关代码:
查询代码:
$pingtreeGroup = PingtreeGroup::where('company_id', $company_id) ->where('id', $id) ->with('pingtrees.tiers') ->withCount('pingtrees.tiers') ->first();
PingtreeGroup的关联:
/** * Get the pingtrees for the model */ public function pingtrees() { return $this->hasManyThrough( Pingtree::class, PingtreeEntry::class, 'pingtree_group_id', 'id', 'id', 'pingtree_id' ); }
问题原因
Laravel的withCount不支持直接用关联.子关联这种点语法统计嵌套关联的数量,它要求参数必须是当前模型上直接定义的关联方法名,而非嵌套的关联路径。
解决方案1:在withCount中用闭包统计子关联
统计所有关联pingtree的tiers总数
$pingtreeGroup = PingtreeGroup::where('company_id', $company_id) ->where('id', $id) ->with('pingtrees.tiers') ->withCount([ 'pingtrees' => function ($query) { $query->select(DB::raw('count(tiers.id)')) ->join('tiers', 'tiers.pingtree_id', '=', 'pingtrees.id'); } ]) ->first();
之后可通过$pingtreeGroup->pingtrees_count获取总数。
给每个pingtree单独统计tiers数量
$pingtreeGroup = PingtreeGroup::where('company_id', $company_id) ->where('id', $id) ->with(['pingtrees' => function ($query) { $query->withCount('tiers'); }]) ->first();
每个$pingtreeGroup->pingtrees中的模型都会带有tiers_count属性。
解决方案2:定义直接关联到Tiers的hasManyThrough关联
在PingtreeGroup模型中新增直接关联Tier的方法:
/** * Get all tiers related to the pingtree group */ public function pingtreeTiers() { return $this->hasManyThrough( Tier::class, PingtreeEntry::class, 'pingtree_group_id', // PingtreeEntry的外键 'pingtree_id', // Tier的外键 'id', // PingtreeGroup的主键 'pingtree_id' // PingtreeEntry关联Pingtree的外键 ); }
然后直接使用withCount:
$pingtreeGroup = PingtreeGroup::where('company_id', $company_id) ->where('id', $id) ->with('pingtrees.tiers') ->withCount('pingtreeTiers') ->first();
之后可通过$pingtreeGroup->pingtree_tiers_count获取总数。
内容的提问来源于stack exchange,提问作者Ryan H
相关产品推荐
相关产品推荐

