【发布时间】:2019-09-09 12:24:10
【问题描述】:
⛳ 我需要什么:
我正在Laravel 5.4 中开发一个应用程序,我想要一个global scope,它允许我根据创建它们的用户过滤应用程序的不同元素。
????我的全球范围:
我有一个类BaseEloquentModel.php 扩展Eloquent,我所有的模型都从这个类扩展。我有一个global scope 如下:
protected static function boot()
{
parent::boot();
static::addGlobalScope('', function(\Illuminate\Database\Eloquent\Builder $builder) use($userId) {
/**
* I get the name of the table with <code>(with(new static))->getTable()</code>
* and then filter the query for the <b>user_id</b> field
*/
$builder->where(
(with(new static))->getTable() . '.user_id',
'=',
$userId
);
});
}
⛔ 问题
当我有这样的查询时,使用or 运算符,全局范围被“中和”:
$qBuilderCars = Car::whereRaw("name like ? or id = ?", [
'%' . $searchCriteria. '%',
$searchCriteria
]);
如果我在$qBuilderCars 上调用toSql() 方法,我发现它“正确”将AND 运算符添加到查询末尾。
select * from `cars` where name like ? or id = ? and user_id = ?
也许你已经注意到我的问题...如果元素的构建器,在本例中为cars,使用了OR 运算符,那么全局范围将无济于事,因为@987654338 之间没有括号@。因此,生成的查询将类似于以下内容:
select * from `cars` where name like ? (or id = ? and user_id = ?)
因此,此查询将返回名称匹配或 ID 为已接收并由用户创建的所有汽车...
当我需要的是:
select * from `cars` where (name like ? or id = ?) and user_id = ?
????我的尝试
我尝试更改我的global scope 以尝试使我在查询中添加的AND 运算符限制最多,但没有任何成功。
我无法为所有应用程序的查询手动添加括号,所以...有没有办法将全局括号从全局范围添加到builder?
????解决方案
解决方案是为所有原始查询添加括号。
✅✅你可以看到我认为最成功的@Styx solution
我还将 leave my answer,它直接在
global scope内部起作用,我认为能够看到\Illuminate\Database\Eloquent\Builder对象如何工作很有趣
【问题讨论】:
-
哪个是laravel版本?因为在 laravel 5.2 中,当应用全局范围时,默认情况下会根据需要添加括号。
-
是
Laravel 5.4并且不会自动添加括号:-S -
@yrv16 你能给我看看这方面的文档吗?
-
我已经安装了 5.4 并且在 5.2 版本中的查询中确实没有括号。我发现全局范围实现已被重写的信息。 laravel.com/docs/5.3/upgrade
-
@yrv15 首先,感谢您抽出宝贵时间。哇,可惜
Laravel 5.4全局范围发生了变化。我认为我唯一能做的就是尝试看看他们如何引入这些括号以在我的应用程序中复制它......
标签: php laravel eloquent scope