我遗漏了全局范围在Laravel 5.5中的工作方式。
在我的控制器index
中,我将过滤器传递给getter:
public function index(SaleFilters $filters)
{
return new SaleCollection($this->getSales($filters));
}
getSales
:
protected function getSales(SaleFilters $filters)
{
$sales = Sale::with('office')->filter($filters);
return $sales->paginate(50);
}
protected function range($range)
{
$dates = explode(" ", $range);
if (count($dates) == 2) {
$this->builder = Sale::with(['office', 'staff'])
->where('sale_date', '>=', $dates[0])
->where('sale_date', '<', $dates[1])
->orderBy('sale_date', 'desc');
return $this->builder;
}
return false;
}
我在sale
模型中有一个范围设置,我原本认为它会自动应用于上面的过滤器吗?如果没有,我是否必须重新应用相同的范围,复制过滤器中的范围代码?
protected static function boot()
{
parent::boot();
$user = Auth::user();
if (($user) && ($user['office_id'])) {
return Sale::ofOffice($user['office_id'])->get();
}
}
public function scopeOfOffice($query, $office)
{
return $query->where('office_id', $office);
}
基本上,如果用户已应用office_id
,则应该应用ofOffice
范围,因此它应该只返回适用于office_id
的销售额。
基本上它适用于通过axios GET请求的页面加载
Route::get('/sales', 'SalesController@index')->middleware('auth:api');
axios
.get('api/sales/?range=" + this.rangeFilter)
rangeFilter
基本上是传入上述过滤器查询的开始日期和结束日期。
任何人都可以了解范围如何真正起作用,或者是否有任何明显的原因并不总是有效?正如我所说,它适用于页面加载,我提供rangeFilter
的默认值,但是当我更改那些日子并通过相同的axios调用重新获取时,似乎没有应用范围,我得到所有结果而不是where office_id = 'x'
就我而言,上面的范围过滤器也会在第一页加载时执行,因此不确定为什么它会在那里应用,而不是之后。
答案 0 :(得分:1)
您不应将动态范围与全局范围混合使用。此外,静态boot
函数不期望返回。要使用动态范围,您需要在每次需要时调用它。因此,名称是动态的。默认情况下,并不总是执行应用的查询。那么,
protected function getSales(SaleFilters $filters)
{
$sales = Sale::ofOffice($anyOfficeHere)->with('office')->filter($filters);
return $sales->paginate(50);
}
要适合您现有的代码,您可能需要在模型中添加if
语句。然后不带参数调用scope函数。
public function scopeOfOffice($q)
{
if (($user = \Auth::user()) && ($office = $user->office_id)) {
$q->where('office_id', $office);
}
}
// Your controller
protected function getSales(SaleFilters $filters)
{
$sales = Sale::ofOffice()->with('office')->filter($filters);
return $sales->paginate(50);
}
如果您反复输入ofOffice
感到非常麻烦。全球范围是要走的路。在你的模型静态boot
函数中,如果你觉得创建一个单独的类有点膨胀你的应用程序,你也可以应用匿名函数。
protected static function boot()
{
parent::boot();
static::addGlobalScope('officeOrWhatNot', function ($q) {
if (($user = \Auth::user()) && ($office = $user->office_id)) {
$q->where('office_id', $office);
}
});
}
// Your controller. No more `ofOffice`, it's automatically applied.
protected function getSales(SaleFilters $filters)
{
$sales = Sale::with('office')->filter($filters);
return $sales->paginate(50);
}