Eloquent关联查询获取Campaign价格报错,如何正确获取?
解决Laravel中关联集合访问属性的报错问题
嘿,这个问题我之前也碰到过,咱们一步步拆解原因和解决方案:
错误原因分析
你看到的报错 Property [price] does not exist on this collection instance. 本质是:
你的Product模型和Campaign模型的关联关系应该是一对多(比如一个商品可以有多个活动),所以当你通过$product->campaign访问关联数据时,返回的是一个Collection集合对象,而不是单个Campaign模型。集合本身没有price属性,直接访问就会报错。
另外,你的控制器代码还有个小问题:->first()方法已经返回了单个Product模型,之后再调用->orderBy('price', $sort)是完全无效的,排序逻辑应该放在first()之前。
解决方案分两种情况处理
情况1:每个商品只有一个有效活动(一对一关联)
如果你的业务逻辑是一个商品最多对应一个有效的活动,那先修改Product模型的关联定义,把过滤条件直接写在关联里:
// app/Models/Product.php public function campaign() { return $this->hasOne(Campaign::class) ->where('stock', '>', 0) ->where('expire', '>', \Carbon\Carbon::today()->toDateString()); }
然后简化控制器的查询代码,同时修正排序和first()的顺序:
$query = Product::where('quantity', '>', 0) ->whereNotNull('product_category_id') // 用whereNotNull比where('!=', null)更规范 ->where('soft_delete', 0) ->whereBetween('price', [$priceFrom, $priceTo]) ->with('campaign') ->orderBy('price', $sort) ->first(); // 先排序再取第一个商品
最后视图里就可以直接访问单个活动的属性了:
@if($product->campaign) <del>$425.00</del> {!! $product->campaign->price !!} @endif
情况2:每个商品可以有多个有效活动(一对多关联)
如果业务允许一个商品有多个有效活动,那视图里需要处理集合对象:
- 如果你只想取第一个有效活动的价格:
@if($product->campaign->isNotEmpty()) <del>$425.00</del> {!! $product->campaign->first()->price !!} @endif
- 如果你要遍历所有有效活动:
@foreach($product->campaign as $campaign) <del>$425.00</del> {!! $campaign->price !!} @endforeach
另外,控制器里的with闭包是没问题的,它会过滤出符合条件的活动集合,但注意要把first()移到orderBy之后,确保排序生效。
内容的提问来源于stack exchange,提问作者Yousef Altaf
相关产品推荐
相关产品推荐

