💭

【Laravel Eloquent】 子テーブルのレコードを条件に応じて集計

2023/03/30に公開

前提

テーブル関係は以下のようなものを想定しています。

親テーブル contents

id name description
1 コンテンツ1 XXX
2 コンテンツ2 YYY

子テーブル votes(コンテンツに対するgood/badなどのユーザーからの評価)

id content_id is_positive
1 1 ture
2 1 false
3 1 true

GET /api/contents/get/1
のようなAPIが呼ばれた際に、以下のようにvotesテーブルのis_positiveに応じた集計値を含めてレスポンスしたい場合を想定しています。

response.json
{
    "content": {
        "id": 1,
        "name": "コンテンツ1",
        "description": "XXX",
        "positive_vote_count": 2,
        "negative_vote_count": 1,
    }
}

Laravel Eloquentを利用したコード例

以下のように、withCountとfunction ($query) を用いることでvotesテーブルのis_positiveに応じた集計値をレスポンスに含めることができるようになります。

$contentId = $request->content_id;

Content::find($contentId)->withCount(
	['votes as positive_vote_count' => function ($query) {
            $query->where('is_positive', true);
        }, 'votes as negative_vote_count' => function ($query) {
            $query->where('is_positive', false);
        }])->first();

今回はis_positiveはbool型でしたが、ユーザーの属性などtrue/falseの2値では表せないものであっても、function ($query) {}内を調整してあげれば、集計できるようになるかと思います。

Discussion