使用雄辩的关系来计算品牌的产品和评论


Count products and reviews of a brand using eloquent relationhips

>我有三个模型:

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) }}