1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

EloquentのwithCountメソッドでリレーション先のレコード数を取得する方法

Posted at

はじめに

「リレーション先のレコードは使わないけど、取得したレコードの数は見たい」という状況が稀にあります
自分はリレーション先のカラムをidにしView側でCountしていましたが、これをModelだけで実現できるwithCountメソッドに感動したので解説していきます

withCountメソッドの基本

withCountメソッドは、リレーションシップのレコード数をカウントし、結果に追加するために使用されます
例えば、Userモデルが複数の投稿(posts)を持っている場合、各ユーザーの投稿数をカウントして取得できます
これは非常に便利です

基本的なwithCountの使用

ユーザーモデルとポストモデルが1対多の関係にある場合、以下のようにwithCountメソッドを使用します

モデルの定義

User.php
public function posts()
{
  return $this->hasMany(Post::class);
}

クエリの使用例

$users = User::withCount('posts')->get();

foreach ($users as $user) {
  echo $user->name . ' has ' . $user->posts_count . 'posts.';
}

このクエリにより、各ユーザーのposts_countプロパティに投稿数が格納されます

複数リレーションシップのカウント

withCountメソッドは、複数のリレーションシップを同時にカウントすることもできます

$users = User::withCount(['posts', 'comments'])->get();

foreach ($users as $user) {
  echo $user->name . ' has ' . $user->posts_count . ' posts and ' . $user->comments_count . ' comments.';

このクエリでは、**各ユーザーのposts_countcomments_countプロパティに、それぞれの投稿数とコメント数が格納されます

条件付きカウント

特定の条件に基づいてカウントすることも可能です

$users = User::withCount(['posts' => function ($query) {
  $query->where('status', 'published');
}])->get();

foreach ($users as $user) {
  echo $user->name . ' has ' . $user->posts_count . ' published posts';
}

このクエリでは、statuspublishedの投稿のみをカウントします

まとめ

withCountメソッドを使用することで、Eloquentモデルにおける関連データのカウントが非常に簡単になります
このメソッドは、データの分析や表示において強力なツールとなり、クエリの効率性を向上させます
すくなくともViewでCountさせるという手間は省けると思います
ぜひプロジェクトで活用してみてください

参考リンク

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?