Laravel: how to get average on nested hasMany relationships (hasManyThrough)

巧了我就是萌 提交于 2019-11-30 15:04:18

You need something like this http://softonsofa.com/tweaking-eloquent-relations-how-to-get-hasmany-relation-count-efficiently/ only slightly adjusted to match your needs:

public function reviewRows()
{
    return $this->hasManyThrough('ReviewRow', 'Review');
}

public function avgRating()
{
    return $this->reviewRows()
      ->selectRaw('avg(rating) as aggregate, product_id')
      ->groupBy('product_id');
}

public function getAvgRatingAttribute()
{
    if ( ! array_key_exists('avgRating', $this->relations)) {
       $this->load('avgRating');
    }

    $relation = $this->getRelation('avgRating')->first();

    return ($relation) ? $relation->aggregate : null;
}

Then as simple as this:

// eager loading
$products = Product::with('avgRating')->get();
$products->first()->avgRating; // '82.200' | null

// lazy loading via dynamic property
$product = Product::first()
$product->avgRating; // '82.200' | null

Maybe you can try with Eloquent relationships and a little help from php function array_reduce

//model/Reviews.php
public function sum() {
    return array_reduce($this->hasMany('ReviewRows')->lists('rating'), "sumItems");  
}

public function sumItems ($carry, $item) {
    $carry += $item;
    return $carry;
}

Or with Eloquent RAW querys like:

//model/Reviews.php
public function avg() {
   $result = $this->hasMany('ReviewRows')
   ->select(DB::raw('avg(rating) average'))
   ->first();
   return $result->average;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!