php - Laravel - 如何用 builder 上的 where 子句包围所有先前的子句?
问题描述
在数据库表中,我有一行:
users
id|email|is_deleted
1|test@test.com|1
我有这个代码:
User::where('email', 'test@test.com')
->orWhere('email', 'test2@test2.com')
->get();
并生成此查询:
select * from users where email = 'admin@myzone.com' or email = 'asdasdas'
有一个结果。现在我想申请 where is_deleted = 0
如果我喜欢这样:
User::where('email', 'test@test.com')
->orWhere('email', 'test2@test2.com')
->where('is_deleted', 0)
->get();
生成的查询是:
select * from "users" where "email" = ? or "email" = ? and "users"."deleted_at" is null
到目前为止,一切都按预期工作,此查询返回一个结果,但我只想不删除用户,我可以执行以下操作:
User::where(function($query){
$query->where('email', 'test@test.com')
->orWhere('email', 'test2@test2.com')
})->where('is_deleted', 0)
->get();
这会起作用,但在我的代码中我已经返回了 builder :
function applyNotDeleted(Builder $builder){
//here I want to filter only not deleted users,
//but this is already triggered on builder $query->where('email', 'test@test.com')->orWhere('email', 'test2@test2.com')
//currently generated query on builder is select * from users where email = 'admin@myzone.com' or email = 'asdasdas'
//but at this stage I want to create query which will look like select * from "users" where "email" = ? or "email" = ? and "users"."deleted_at" is null
//something like this
$builderNew = $builderNew->where(function($query){
$query->applyAllLogicFromCurrentBuilder($builder)
})
->where('is_deleted', 0)
->get();
}
任何想法?
解决方案
我个人会使用查询范围来获取未删除的记录
public function scopeNotDeleted(Builder $query): Builder
{
return $query->where('is_deleted', 0);
}
然后在获取记录时使用它
User::notDeleted()->where(function(Builder $query) {
$query->where('email', 'test@test.com')->orWhere('email', 'test2@test2.com');
})->get();
如果您正在使用applyAllLogicFromCurrentBuilder
方法,您还可以将其提取到查询范围,然后将其与您的调用链接起来,如下所示:
User::allLogicFromCurrentBuilder()->notDeleted()->where(function(Builder $query) {
$query->where('email', 'test@test.com')->orWhere('email', 'test2@test2.com');
})->get();
您也可以保持applyNotDeleted
方法不变,但不调用get()
方法 - 这样您可以在需要时向其附加任何进一步的语句。我可能会将它转换为一种public static
方法,这样您就可以在不实例化模型的情况下调用它:
User::applyNotDeleted(User::where(function(Builder $query) use ($email) {
$query->where('email', 'test@test.com')->orWhere('email', 'test2@test2.com');
}))->get();
就个人而言,我更喜欢范围方法,因为它看起来更干净。
推荐阅读
- elasticsearch - 如何查询最近 1 小时的数据并按时间排序?
- react-native - Stacknavigator 中 Tabnavigator 的导航
- c# - 向 DbContext 添加新对象时实体框架中的空引用异常
- javascript - three.js mtl 加载器呈现黑色
- c# - 如何将布尔列绑定到 DataGridView 中的切换按钮
- swift - 将文本添加到字符串
- excel - 如何在power pivot excel中进行范围索引和匹配或vlookup?
- php - 错误:当我试图从关系表 Yii2 中获取属性时,试图获取非对象的属性
- excel - excel唯一值:查找没有对应匹配的行
- bash - 如何在bash中解析带有逗号分隔的引用子字符串列表的字符串?