>我有三个模型:
class Brand extends 'Eloquent {
protected $fillable = [];
public function product()
{
return $this->hasMany('Product');
}
}
class Product extends 'Eloquent {
protected $fillable = [];
public function reviews()
{
return $this->hasMany('Review');
}
public function brand()
{
return $this->belongsTo('Brand');
}
}
class Review extends 'Eloquent {
protected $fillable = [];
public function product()
{
return $this->belongsTo('Product');
}
}
我正在尝试在视图中显示品牌名称以及产品和评论计数:
{{ $brand->product->count() }}
它适用于此,但不显示评论计数:
{{ $brand->product->reviews->count() }}
既不为:
{{ $brand->product->reviews->count() }}
我收到的错误是:
ErrorException (E_UNKNOWN)
Undefined property: Illuminate'Database'Eloquent'Collection::$review
ErrorException (E_UNKNOWN)
Undefined property: Illuminate'Database'Eloquent'Collection::$reviews
问题是你不能在模型的集合上调用关系,而只能在模型本身上调用关系。这意味着您必须遍历产品并计算每个产品的评论。
基本上是这样的
$counter = 0;
foreach($brand->product as $product){
$counter += $product->reviews()->count();
}
echo $counter.' reviews!';
现在这对数据库性能非常不利。首先,它查询产品,然后为每个产品向数据库发出另一个请求。我们可以使用预先加载来避免这种情况。
$counter = 0;
$products = $brand->product()->with('reviews')->get();
foreach($products as $product){
$counter += $product->reviews()->count();
}
echo $counter.' reviews!';
通过预先加载,它通过一个查询加载所有数据,并且当我们执行$product->reviews()
时,它已经在内存中
为了完成这里的事情,我们现在可以把它放在品牌模型的一个函数中
public function getProductReviewCount(){
$counter = 0;
$products = $this->product()->with('reviews')->get();
foreach($products as $product){
$counter += $product->reviews()->count();
}
return $counter;
}
{{ $brand->getProductReviewCount() }}
旁注:我还建议您将关系product
的名称更改为products
。使用复数更有意义,通常是惯例。
我正在使用 {{ count($brand->product) }} {{ count($brand->product->reviews) }}