来自同一模型的多个模型的计数关系

Posted

技术标签:

【中文标题】来自同一模型的多个模型的计数关系【英文标题】:Count relationship for multiple models coming from the same model 【发布时间】:2020-10-27 13:08:12 【问题描述】:

我有以下三个模型:用户、帖子和评论。一个用户可以有多个帖子,每个帖子可以有多个 cmets。

我想做的是:

获取属于特定用户的所有帖子中所有 cmets 的计数 获取本月属于同一用户的所有帖子中所有 cmets 的计数 起点是按 ID 的特定帖子(因此不是从用户 ID 开始)。

请看下面我现在所拥有的,这是可行的。

我的问题是:是否可以将执行 ->sum() 的最后两行添加到查询中?

我认为这个查询已经很漂亮了,但它看起来会更好,但更重要的是,如果最后两行也包括在内,它将使缓存变得容易得多。

$post = Post::findOrFail($id);

$posts = Post::where('user_id', $post->user_id)
        ->withCount(['comments as comments_total'])
        ->withCount([
            'comments as comments_this_month' => function ($q) 
                $q->whereBetween('created_at',
                    [ Carbon::now()->startOfMonth(), Carbon::now()->endOfMonth() ]
                );
            ,
        ])->get();
);

$comments_this_month_count = $posts->sum('comments_this_month');
$comments_total_count = $posts->sum('comments_total');

【问题讨论】:

【参考方案1】:

我可以只用两行代码提出一个更好的解决方案。

在您的User 模型中定义hasManyThrough 关系:

public function comments()

    return $this->hasManyThrough(
        Comment::class,
        Post::class,
        'user_id', // Foreign key on posts table...
        'post_id' // Foreign key on comments table...
    );

那就这样称呼它吧:

$comments_this_month_count = User::find($post->user_id)->comments()
->whereMonth('created_at', now()->month)->count();

$comments_total_count = User::find($post->user_id)->comments()->count();

【讨论】:

使用HasManyThrough 是个好主意。虽然现在我仍然有 2 行代码用于 2 个计数,就像我现在一样。如果我可以将它们放在 1 个查询中,则更容易缓存,尽管我可能不得不增加这些计数。

以上是关于来自同一模型的多个模型的计数关系的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 多模型关系返回计数

Laravel Eloquent:计数项目模型关系

如何为对象计数多个关系创建谓词?核心数据 iOS Swift

获取核心数据中一对多关系的计数

相关模型的 Laravel 计数列

如何在 Laravel 4 中选择相关模型计数为 0 的模型?