Laravel WhereHas 与多态关系

edi*_*999 3 php mysql polymorphic-associations laravel laravel-4

似乎 whereHas 方法不能很好地工作。

$res = Entreprise::whereHas('labels',function ($q)
    {
        $q->where('hidden','!=',1);
    })
    ->whereHas('labels',function ($q)
    {
        $q->whereHidden(1);
    })
    ->get();
 dd(count($res));  //shows int 2
Run Code Online (Sandbox Code Playgroud)

这是标签关系:

public function labels()
{
    return $this->morphToMany('Label', 'labelable');
}
Run Code Online (Sandbox Code Playgroud)

这是数据库:

id | nom                | deleted_at | created_at          | updated_at          | junior_id | label_type_id | abbreviation | id_siaje | hidden 
 6 | Environnord        | 0000-00-00 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |         1 |             4 | EnvNord      |        0 |      1 
 7 | Salon créer        | 0000-00-00 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |         1 |             4 | Créer        |        0 |      1 
 8 | Salon WebAnalytics | 0000-00-00 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |         1 |             4 | Web          |        0 |      0 
Run Code Online (Sandbox Code Playgroud)

当我这样做时:

$res = Entreprise::whereHas('labels',function ($q)
    {
        $q->where('hidden','!=',1);
        $q->whereHidden(1);
    })->get()
dd(count($res)); //int 0
Run Code Online (Sandbox Code Playgroud)

我得到了预期值。

在我的数据库中,一个企业对象的标签不超过 1 个,因此标签是隐藏的还是不隐藏的,因此条件之一应该为假。

编辑

这是可标记的表

+----+----------+--------------+----------------+-----------+
| id | label_id | labelable_id | labelable_type | junior_id |
+----+----------+--------------+----------------+-----------+
|  1 |        1 |          925 | Etude          |         1 |
|  2 |        2 |          926 | Etude          |         1 |
|  3 |        3 |          927 | Etude          |         1 |
|  4 |        2 |          927 | Etude          |         1 |
|  5 |        1 |          928 | Etude          |         1 |
|  6 |        2 |          928 | Etude          |         1 |
|  7 |        3 |          929 | Etude          |         1 |
|  8 |        2 |          931 | Etude          |         1 |
|  9 |        1 |          933 | Etude          |         1 |
| 10 |        2 |          934 | Etude          |         1 |
| 11 |        4 |            1 | User           |         1 |
| 12 |        5 |            2 | User           |         1 |
| 13 |        7 |            1 | Entreprise     |         1 |
| 14 |        6 |            2 | Entreprise     |         1 |
| 15 |        7 |            3 | Entreprise     |         1 |
| 16 |        8 |            4 | Entreprise     |         1 |
| 17 |        6 |            5 | Entreprise     |         1 |
| 18 |        7 |            6 | Entreprise     |         1 |
| 19 |        6 |            7 | Entreprise     |         1 |
+----+----------+--------------+----------------+-----------+
Run Code Online (Sandbox Code Playgroud)

如您所见,问题可能是它们是两个 labelable_id 为 1 的实体,以及两个 labelable_id 为 2 的实体。但这是一个 morphToMany,所以 Eloquent 应该知道不应该考虑用户的标签?

当我查看生成的 SQL 时:

 select * from `entreprises` 
     where `entreprises`.`deleted_at` is null
     and `entreprises`.`junior_id` = ? 
     and (select count(*) from `labels` 
          inner join `labelables` on `labels`.`id` = `labelables`.`label_id` 
          where `labels`.`deleted_at` is null 
          and `labels`.`junior_id` = ? 
          and `labelables`.`labelable_id` = `entreprises`.`id` 
          and `hidden` != ?
          and `hidden` = ?
          and `labels`.`deleted_at` is null
          and `labels`.`junior_id` = ?) >= ?
Run Code Online (Sandbox Code Playgroud)

似乎labelables.labelable_type没有考虑到,所以这可能是问题的根源。

Joo*_*ost 6

虽然我不知道问题是什么,但我敢打赌你实际上得到了正确的答案,而你的期望是不正确的。

你的第二个例子有一个 whereHas显然不会返回任何行,因为条件永远无法满足。

然而,对于第一个,我想你的理解是有缺陷的。生成的查询反映了您指定的两个whereHas子句。它会查找所有至少有一个隐藏标签的企业,以及至少一个未隐藏标签的企业。既然是多对多的关系,这其实是可以满足的。

请注意,这与第二个示例不同,在第二个示例中,您搜索具有至少一个隐藏和未隐藏标签的所有企业。

我不知道enterprise表,也不知道many-many join表,但我猜这两个结果实际上满足我上面所说的条件。您的数据库引擎可能不会说谎。如果您不这么认为并且觉得生成的查询实际上是错误的,请告诉我们您认为它错误的地方。

  • 只需添加对通过搜索结束的其他人的错误报告的引用,https://github.com/laravel/framework/issues/3068 (3认同)