首页 文章

Laravel动态范围仅适用于第一次

提问于
浏览
0

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

  • 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);
    }
    

相关问题