Laravel 多个 whereHas 关系标准

问题描述 投票:0回答:3

我有两个表 - 联系人和访问:

联系方式表

id    | name          
----- | -------
1     | Joe
2     | Sally

参观表

id    | contact_id | pathname  | referrer                
----- | -------    | -------   | -------
1     | 1          | about     | google
2     | 1          | pricing   | null
3     | 1          | signup    | null
4     | 2          | about     | null
5     | 2          | signup    | null

使用雄辩,我想检索所有具有 pathname = 'signup' 和 referrer = 'google' 的 contacts

到目前为止我所得到的是:

Contact::whereHas('visits', function($query) {
    $query->where('pathname','=','signup');
})
->orWhereHas('visits', function($query) {
    $query->where('referrer','=','google');
})
->get();

它可以正确检索访问过定价或注册页面的所有联系人。

但是,此示例还会检索 Sally(来自上面的示例表),因为她访问了注册,但未被 google 引用。我需要一种方法来只检索Joe,他是由谷歌推荐并访问过定价的。

有什么想法吗?预先感谢!

laravel eloquent relationship
3个回答
25
投票

您可以使用:

Contact::whereHas('visits', function($query) {
    $query->where('pathname','=','signup');
})
->whereHas('visits', function($query) {
    $query->where('referrer','=','google');
})
->get();

19
投票

上述代码的精炼版本:

Contact::whereHas('visits', function($query) {
    $query->where('pathname','signup')->where('referrer','google');
})->get();

几个值得注意的点:

  1. 您可以在闭包中链接
    where()
    子句。
  2. where 子句的默认运算符是
    =
    ,因此您可以省略它。
  3. 访问多个相关模型时,使用多个
    whereHas()
    子句。

0
投票

Первый ответ с двумя 其中 дважды делает 加入 к одной 和 той же таблице, что не очень хорошо。 Второй ответ не будет работать поскольку на участке

$query->where('pathname','signup')->where('referrer','google');
каждая строка таблицы 访问 будет проверяться на соответствие обоим условиям,но каждая из них по отдельности не соответствует двум условиям。 Вам необходимо использовать подход с подсчетом на соответствие общему количеству условий:

$total_number_of_conditions = 2; // общее количество условий where
    Contact::whereExists(function (Builder $b) use (int $total_number_of_conditions) {
        $b->selectRaw('COUNT(*) as count')
            ->from('visits')
            ->whereColumn('сontacts.id', 'сontact_id')
            ->where('pathname', 'signup')->where('referrer', 'google'))
            ->having('count', $total_number_of_conditions);
    })->get();
© www.soinside.com 2019 - 2024. All rights reserved.