Use this:
class Post extends Eloquent {
// if you don't want it to be appended always, don't set this one - see below
protected $appends = ['rating'];
protected $hidden = ['ratingsSum'];
public function ratingsSum() {
return $this->hasOne('Rating')
->selectRaw('sum(rating) as aggregate, post_id')
->groupBy('post_id');
}
public function getRatingAttribute()
{
if ( ! array_key_exists('ratingsSum', $this->relations)) $this->load('ratingsSum');
$relation = $this->getRelation('ratingsSum');
return ($relation) ? $relation->aggregate : 0;
}
}
Then you can do this:
$posts = Post::with('ratingsSum')->get();
$posts->toArray();
array(
...
'rating' => '8'
)
// but mind that without eager loading you will face n+1 queries issue:
$posts = Post::get();
$posts->toArray(); // db call for ratingsSum() for each post
If the above (using $appends
) doesn't suit you, don't set it and instead do this:
$posts = Post::with('ratingsSum')->get();
foreach ($posts as $post) { $post->setAppends(['rating']); } // when you need it
or leave $appends but don't load rating on demand in the accessor
public function getRatingAttribute()
{
$relation = array_get($this->relations, 'ratingsSum');
return ($relation) ? $relation->aggregate : null;
}
// then
$posts = Post::get();
// 'rating' => null
$posts = Post::with('ratingsSum')->get();
// 'rating' => '8'
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community