2017-12-04 5 views
0

Laravel 5.5でのグローバルスコープの動作方法が不明です。私のコントローラでLaravelダイナミックスコープは初めてのみ動作します

indexは、私がゲッターにフィルタを渡しています:

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を持っているのであれば基本的には、それゆえ、それが唯一のこれまでそのoffice_idに適用される売上高を返す必要があり、ofOfficeスコープを適用する必要があります。

は、基本的には

Route::get('/sales', '[email protected]')->middleware('auth:api'); 

axios 
    .get('api/sales/?range=" + this.rangeFilter) 

rangeFilterは基本的に上記のフィルタクエリに渡され、開始日と終了日であるaxios GET要求を経由して、ページの読み込みに取り組んでいます。

スコープが実際にどのように機能しているか、何かがいつもうまくいかない理由が分かっているかについては、誰かが少し光を当てることができますか?私が言ったように、それはrangeFilterのデフォルト値を提供するページロードで動作しますが、私はその日を変更して同じAxiosコールで再フェッチするとスコープが適用されないように見え、where office_id = 'x'

私の言う限り、上記の範囲フィルタは最初のページの読み込み時にも実行されるため、なぜそれがそこに適用されるのか、それ以降は適用されないのか分かりません。

+0

まず、ローカルスコープのアイデア(scopeOfOffice')とグローバルスコープのソートの実装を混在させているようです。たぶん、あなたのスコープをドキュメンテーション[states](https://laravel.com/docs/5.5/eloquent#global-scopes)として実装しようとする価値があるかもしれません。つまり、別のクラスとしてsopeを使用し、次に使用される 'addGlobalScope'メソッド'ブート'で。グローバルスコープクラスの 'Auth :: user()'チェックを直接行うことはできません。 – lesssugar

+0

実際に私はそれを "ダイナミックスコープ"に関するドキュメントの状態として実装しました – yoyoma

+0

ああ、わかりました。 – lesssugar

答えて

1

ダイナミックスコープとグローバルスコープを混在させないでください。また、静的boot関数は返品を期待していません。ダイナミックスコープを使用するには、必要なときにいつでも呼び出す必要があります。したがって、名前は動的です。適用されるクエリは、デフォルトでは必ずしも実行されません。そこので、あなたがあなたのモデルにifステートメントを追加することも、既存のコードを、合わせて

protected function getSales(SaleFilters $filters) 
{ 
    $sales = Sale::ofOffice($anyOfficeHere)->with('office')->filter($filters); 

    return $sales->paginate(50); 
} 

。スコープ関数を引数なしで呼び出します。

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関数内で、別のクラスを作成してアプリを膨らませるように感じる場合は、匿名関数を適用することもできます。

+0

ああ!この2番目のオプションは、私が後にしていることです - 私はちょうどoffice_idをクロージャに渡す方法を考え出すことができませんでした。数時間後にそれを試してみて、あなたの答えをマークしてください、ありがとう! – yoyoma

+0

素晴らしい、作品!私には 'addGlobalScope'の中に受け取った' $ office 'があるので、where句で利用できます – yoyoma

関連する問題