是否有更有效的方法来获取视图中的模型计数? Laravel

时间:2015-03-30 18:37:39

标签: laravel-4 eloquent blade

我有图像。每张图片都有评论,每条评论都有喜欢。在我看来,我想通过这样的方式显示评论的数量:

@foreach ($images as image)
    <img href="$image->url">
    <div class="comment-box">
        @foreach ($image->comments as $comment)
            <div class="comment">
                <span class="comment-owner">{{ $comment->owner()->name }}</span>&nbsp;{{ $comment->body }}
                <div class="likes">
                      {{ $comment->likes()->count() }} // ** HERE IS MY N+1 PROBLEM **
                </div>
            </div>
        @endforeach
    </div>
@endforeach

但是现在我每次有评论时都会提取查询。页面上可能有数百条评论,因此只需查找数百条查询即可找到喜欢的count()

我相信有一种方法可以通过执行类似

的操作来获取控制器中的计数
DB::raw('count(*) as like_count')

但我不知道如何在我的情况下实现这一点。我可以将这种东西放在我的模型中,这样我就可以像{{ $comment->likes()->like_count }}那样打电话吗?如何在没有N + 1问题的情况下使$comment->likes->count()工作?

以下是一些代码:

媒体模型

class Media extends Eloquent {
    public function comments()
    {
        return $this->hasMany('Comment');
    }
}

评论模型

class Comment extends Eloquent {
    public function media()
    {
        return $this->belongsTo('Media');
    }

    public function likes()
    {
        return $this->hasMany('Like');
    }
}

喜欢模特

class Like extends Eloquent {
    public function comment()
    {
        return $this->belongsTo('Comment');
    }
}

我的控制器

public function imageViewer($id)
{
    $images = Media::with(['comments' => function($query) {
                  $query->with('likes');
              }])->where('resource_id', $id)->simplePaginate(1);
    return View::make('image-viewer', compact('images'));
}

1 个答案:

答案 0 :(得分:2)

为什么不使用像count($comment->likes)这样的刀片计数,假设$comment->likes获得评论的喜欢列表

@foreach ($images as image)
    <img href="$image->url">
    <div class="comment-box">
        @foreach ($image->comments as $comment)
            <div class="comment">
                <span class="comment-owner">{{ $comment->owner()->name }}</span>&nbsp;{{ $comment->body }}
                <div class="likes">
                      {{ count($comment->likes) }} 
                </div>
            </div>
        @endforeach
    </div>
@endforeach

感谢@lukasgeiter在评论中指出错误