You can't do that using with
, because it executes separate query.
What you need is simple join
. Just translate the query you have to something like:
Posts::join('comments as c', 'posts.id', '=', 'c.id')
->selectRaw('posts.*, count(distinct c.id) as numComments')
->groupBy('posts.id', 'posts.post_title')
->with('user', 'vote', 'tags')
->get();
then each post in the collection will have count attribute:
$post->numComments;
However you can make it easier with relations like below:
Though first solution is better in terms of performance (might not be noticeable unless you have big data)
// helper relation
public function commentsCount()
{
return $this->hasOne('Comment')->selectRaw('posts_id, count(*) as aggregate')->groupBy('posts_id');
}
// accessor for convenience
public function getCommentsCountAttribute()
{
// if relation not loaded already, let's load it now
if ( ! array_key_exists('commentsCount', $this->relations)) $this->load('commentsCount');
return $this->getRelation('commentsCount')->aggregate;
}
This will allow you to do this:
$posts = Posts::with('commentsCount', 'tags', ....)->get();
// then each post:
$post->commentsCount;
And for many to many relations:
public function tagsCount()
{
return $this->belongsToMany('Tag')->selectRaw('count(tags.id) as aggregate')->groupBy('pivot_posts_id');
}
public function getTagsCountAttribute()
{
if ( ! array_key_exists('tagsCount', $this->relations)) $this->load('tagsCount');
$related = $this->getRelation('tagsCount')->first();
return ($related) ? $related->aggregate : 0;
}
More examples like this can be found here http://softonsofa.com/tweaking-eloquent-relations-how-to-get-hasmany-relation-count-efficiently/
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…