Laravelのモデルのスコープとは簡単にいうと SQL文の「 WHERE aaa = 'bbb'」みたいなWHERE句 なのですが、
・「User」モデルの中の管理者フラグを持つものだけを取り扱う
・「User」モデルが既にあるときに、現在削除されてないユーザー( WHERE is_deleted = 0 )を「Activeuser」モデルとして作成する。
みたいなところで使います。
その時に使うのが モデルの「スコープ」です。
好きな時につけたり外したりできる「ローカルスコープ」と
基本的につけっ放しの「グローバルスコープ」があります。
例:自分(ログインしているユーザー)と同じチームIDを持つという条件を
( Inmyteam )というグローバルスコープとして作成して、モデルに適用します。
/app/Scopes/Inmyteam.php
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
class Inmyteam implements Scope
{
/**
* 自分のチーム内のユーザーに限定するスコープ
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
return $builder->where('team_id', '=', Auth::user()->team_id);
}
}
app/User.php のメソッドに下記の boot() メソッドを追加する
use App\Scopes\Inmyteam;
protected static function boot()
{
parent::boot();
// スコープ「Inmyteam」を適用
static::addGlobalScope(new Inmyteam);
}
以上です。簡単ですね。
なおグローバルスコープに変数は渡せないようなので、ダイナミックに変わる条件(動的なパラメーター)を指定したい場合はセッションなど別のルートから取って来ましょう。
取れない場合はローカルスコープで設定します。
モデルファイル内に記述します。 利点は初めてLaravelを触る方にも見落としがない、という点と記述が楽な点です。
app/User.php のメソッドに下記の boot() メソッドを追加し、その中に直接記述する
// /**
// * boot method
// * @return void
// */
protected static function boot()
{
parent::boot();
// GlobalScope
static::addGlobalScope('report_start', function(\Illuminate\Database\Eloquent\Builder $builder){
$builder->where('team_id', '=', Auth::user()->team_id);
});
}
モデルファイルの中に直接書けばOK。 ローカルスコープはメソッドに引数を渡せます。
例) あるショップ内の商品に限定するスコープを作成する
app/Items.php
/**
* ローカルスコープ : ->inShop(<id>) で あるショップ内の商品に限定する
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeInShop($query, $shop_id)
{
return $query->where('shop_id', '=', $shop_id);
}
shop_id が 99 な商品を全件取得
Item::inShop(99)->all()
実は
Item::inShop(99)
Item::inshop(99)
どちらも使うことができますが、同じようにキャメルケースで使用することをお勧めします。