php laravel wherehas,php-Laravel wherehas具有多态关系

本文探讨了在Laravel中使用whereHas方法进行多条件聚合查询的问题,特别是当标签关系存在多对多关联时。作者指出,理解标签隐藏状态的查询逻辑至关重要,并提供了数据库示例和SQL查询分析。问题可能在于标签的多态关联和查询条件的设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

好像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

标签关系如下:

public function labels()

{

return $this->morphToMany('Label', 'labelable');

}

这是数据库:

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

当我改为:

$res = Entreprise::whereHas('labels',function ($q)

{

$q->where('hidden','!=',1);

$q->whereHidden(1);

})->get()

dd(count($res)); //int 0

我得到了期望值.

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

编辑

这是可贴标签的表格

+----+----------+--------------+----------------+-----------+

| 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 |

+----+----------+--------------+----------------+-----------+

如您所见,问题可能在于它们是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` = ?) >= ?

似乎未考虑labelables.labelable_type,因此这可能是问题的根源.

解决方法:

尽管我不知道问题是什么,但我敢打赌您实际上得到了正确的答案,而您的期望是不正确的.

您的第二个示例具有单处wherehas显然不会返回任何行,因为该条件永远无法满足.

但是,对于第一个,我想您的理解是有缺陷的.生成的查询反映了您使用两个whereHas子句指定的内容.它将查找所有至少具有一个隐藏标签和至少一个没有隐藏标签的企业.由于这是一个多对多的关系,因此这实际上是可以满足的.

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

我不知道企业表,也不知道多连接表,但是我猜这两个结果实际上满足了我上面提到的条件.您的数据库引擎可能不会说谎.如果您认为相反,并且感觉到生成的查询实际上是错误的,请告诉我们您认为错误的地方.

标签:polymorphic-associations,laravel,laravel-4,mysql,php

来源: https://codeday.me/bug/20191122/2058883.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值