laravel - Laravel 复杂的地方和地点
问题描述
我有一个查询,可以让所有用户在 html 复选框数组上选择一些特定技能,这些值是技能数据库中的 ID。
例如,当您具有 Laravel 和 SQL 技能时,搜索查询应仅在用户输入 laravel 和 sql 或其中之一时返回您,否则不应显示您。
现在发生的是另一种方式:当您选择 laravel OR sql 时,它会在用户列表中显示您,但如果您同时选择两者,您将不会,但您仍然拥有这些技能。如果我将 where 替换为 orWhere,它会正常运行,但即使我们输入了您没有的其他技能,也会将您显示为相关用户。
这是我的查询的一部分:
->when(isset($data['skills']) and $data['skills'] != null, function ($query) use ($data){
$query->whereHas('skills', function ($subQuery) use ($data) {
for($i = 0; $i < count($data['skills']); $i++){
$subQuery->where('skills.id', $data['skills'][$i]);
}
});
})
for 只是为了打开前面传来的技能数组。
任何帮助都会很有用。谢谢
解决方案
这里的问题有点微妙:
下面是 whereHas 相关查询的样子:
select * from skills
where (skills.foreign_id = related_table.id
or `id` = ? or `id` = ? ... -- This is the orWhere part
);
正如您所看到的,对于与该关系 ID或那些技能相对应的所有内容(即使它们不属于该人),or 始终为真,因此基本上属于该人的所有内容加上最终将获得的更多行过滤。
你应该做的是:
->when(isset($data['skills']) and $data['skills'] != null, function ($query) use ($data){
$query->whereHas('skills', function ($subQuery) use ($data) {
$subQuery->where(function ($subSubQuery) use ($data) {
for($i = 0; $i < count($data['skills']); $i++){
$subSubQuery->orWhere('skills.id', $data['skills'][$i]);
}
});
});
})
这将产生一个如下所示的关系查询:
select * from skills
where skills.foreign_id = related_table.id
and (`id` = ? or `id` = ?) -- orWhere is now wrapped in parentheses
你当然可以总是这样做:
->when(isset($data['skills']) and $data['skills'] != null, function ($query) use ($data){
$query->whereHas('skills', function ($subQuery) use ($data) {
$subQuery->whereIn('skills.id', $data['skills']);
});
})
推荐阅读
- python - ValueError: Input 0 is in compatible with layersimilarity_model: 预期形状=(None, 224, 224, 3), found shape=(None, None, 224, 224, 3)
- c - 为什么 C 将 FILE 用于标准输入/标准输出流以及文件操作?
- r - dplyr:在特定输出中平均提取 5-95 个分位数
- python - PostgreSQL 行构造函数的 Django `output_type`
- python - BeautifulSoup 无法正确标记 HTML
- javascript - 在过滤嵌套值时按 unix 时间对对象数组进行分组
- java - 关闭android studio后OpenJDK Platform Binary的40个任务继续在后台运行
- python - 如何获取活动鼠标光标图标的文件路径?
- java - 如何通过扫描仪将双精度值导入控制台
- google-sheets - 语法错误:SyntaxError: missing ) after argument list line: 18 file: Code.gs