【问题标题】:Using withCount() on a relationship that has distinct()在具有 distinct() 的关系上使用 withCount()
【发布时间】:2019-09-23 11:18:10
【问题描述】:

我有以下型号:

问题:[title, user_id]

回复:[body, question_id, user_id]

用户:[名称]

如你所见,一个问题有很多回复,一个回复属于一个用户。

我已将 contributors 关系添加到 Question 模型,该模型检索所有已添加回复的用户(使用回复作为连接表):

public function contributors() 
{
    return $this->belongsToMany(User::class, 'replies')->distinct('user_id');
}

我必须使用distinct() 来删除重复项,因为用户可能会针对一个问题发布许多回复,这很好用。

现在问题发生了:

Question::withCount('contributors')->get()

它会忽略对distinct() 的调用,并为我提供添加了回复(包括重复)的用户总数。

知道如何解决这个问题吗?

【问题讨论】:

    标签: laravel laravel-5 eloquent


    【解决方案1】:

    您可以通过向withCount 方法添加回调来实现。

    $questions = Question::withCount('contributors', function ($query) {
        $query->distinct('user_id');
    })->get()
    

    【讨论】:

    • 不幸的是,它没有任何区别。
    • 我认为relationship方法应该只包含relationship的定义,没有distinct。这也可能是我的建议不起作用的原因。
    • 即使我从关系定义中删除了对 distinct 的调用,它也不起作用......它给出了相同的结果。
    • 抱歉回答错误,我检查了 Laravel 文档中的 distinct 方法,它不接受任何参数,所以它应该只是 distinct()。但是,我想知道,你的第一个选择是否有效 - 只是让所有贡献者,他们是不同的吗?因此解决方案可能是在回调方法中只选择 user_ids,然后在查询中调用 distinct。
    • 感谢您的帮助,我不得不像其他答案所说的那样使用原始表达式。
    【解决方案2】:

    从关系中删除 distinct() 并将 withCount() 与原始表达式一起使用:

    public function contributors() 
    {
        return $this->belongsToMany(User::class, 'replies');
    }
    
    Question::withCount(['contributors' => function ($query) {
        $query->select(DB::raw('count(distinct(user_id))'));
    }])->get();
    

    【讨论】:

    • 谢谢,这行得通。但我想这不能与$withCount 属性一起使用来自动包含计数,对吧?
    • 不是直接的,但您可以在模型的构造函数中设置$withCount 属性。
    【解决方案3】:

    这里也可以用变量来区分

    public function contributors() 
    {
        return $this->belongsToMany(User::class, 'replies');
    }
    
    Question::withCount(['contributors' => function ($query) use ($var)  {
        $query->select(DB::raw('count(distinct(user_id))'));
    }])->get();
    

    【讨论】:

      【解决方案4】:

      您需要继续在关系方法中使用 distinct('user_id') 才能使这些操作正常工作:

      $question->contributors()->count();
      $question->contributors->count();
      $question->contributors()->get()->count();
      

      否则在某些情况下你会得到不同的结果。

      【讨论】:

        猜你喜欢
        • 2019-08-06
        • 2019-11-16
        • 2017-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-11
        相关资源
        最近更新 更多