12/08/2018, 15:26

Làm thế nào để đếm quan hệ trong Eloquent một cách hiệu quả?

Bài toán được đặt ra như sau: Bạn muốn lấy ra danh sách các bài viết và số lượng comment của mỗi bài viết đó? Dĩ nhiên trong Model của bạn thiết kế là 1 bài Post sẽ có nhiều Comment // Post model public function comments() { return $this->hasMany('Comment'); } Bạn có thể giải quyết ...

Bài toán được đặt ra như sau:

  • Bạn muốn lấy ra danh sách các bài viết và số lượng comment của mỗi bài viết đó?

Dĩ nhiên trong Model của bạn thiết kế là 1 bài Post sẽ có nhiều Comment

// Post model
public function comments()
{
  return $this->hasMany('Comment');
}

Bạn có thể giải quyết bài toán trên bằng cách sau:

$posts = Post::with('comments')->get(10);

foreach ($posts as $post) {
   $post->comment_count = $post->comments->count();
}

return $posts;

Cách trên hoàn toàn chính xác, nhưng bạn thấy rằng khi lấy tất cả bài viết bạn phải dùng 1 vòng foreach để count comment, ngoài ra là bạn chỉ cần đếm số lượng comment nhưng theo đoạn code trên thì bạn đã lấy tất cả thông tin của comment như là: id, content, createt_at, .... Vậy tại sao bạn không count comment ngay trong query của mình nhỉ? Nếu count trong query thì chúng ta nghĩ ngay đến việc dùng Query builder để Join table, như sau:

$posts = Post::leftJoin('comments', 'comments.post_id', '=', 'posts.id')
  ->select('posts.*', 'count(*) as commentsCount')
  ->groupBy('posts.id')
  ->get(10);

Như vậy sẽ giải quyết được bài toán đặt ra, nhưng nếu như bạn muốn dùng Eloquent, thì bài toán trên sẽ được giải quyết theo cách sau:

// Post model
public function commentsCount()
{
  return $this->hasOne('Comment')
    ->selectRaw('post_id, count(*) as aggregate')
    ->groupBy('post_id');
}

$posts = Post::with('commentsCount')->get(10); Khi ra view bạn hiển thị kết quả như sau: {{ $post->aggregate }}

Chúc các bạn thành công! Nguồn: https://softonsofa.com/tweaking-eloquent-relations-how-to-get-hasmany-relation-count-efficiently/

0