Laravel动态范围仅适用于

时间:2017-12-04 11:24:45

标签: laravel laravel-5

我遗漏了全局范围在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'

就我而言,上面的范围过滤器也会在第一页加载时执行,因此不确定为什么它会在那里应用,而不是之后。

1 个答案:

答案 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);
}