クエリスコープとは?
クエリスコープ(scope)はグローバルスコープとローカルスコープがあります。
グローバルは、特定のモデルを利用する際に毎回呼び出されるスコープです。
ローカルスコープは、利用したいときに都度呼び出すスコープです。
グローバルスコープ
グローバルスコープの作成
スコープクラスの配置は、決まった場所がないため、任意のディレクトリへ自由に配置できます。
とりあえず「App\Scope」へ配置しています。
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class ItemScope implements Scope
{
/**
* 指定のEloquentクエリビルダにスコープを適用
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
$builder->where('created_at', '<', now());
}
}
グローバルスコープの適用
グローバルスコープを適用するには、モデルクラスに、bootedメソッドを作成します。
bootedメソッドには、addGlobalScopeにて、グローバルスコープクラス(これの例だと「ItemScope」)を設定します。
<?php
namespace App\Models;
use App\Scopes\ItemScope;
use Illuminate\Database\Eloquent\Model;
class Item extends Model
{
/**
* モデルの「起動」メソッド
*
* @return void
*/
protected static function booted()
{
static::addGlobalScope(new ItemScope);
}
}
グローバルスコープの呼び出し
// queryのlogを出力する設定
DB::enableQueryLog()
// いつもどおり、Eloquentでデータ取得します。
Item::find(1)
// findすると、グローバルスコープで設定した条件が増えているのがわかります。
DB::getQueryLog()
匿名のグローバルスコープ
グローバルスコープクラスを作らなくても、クロージャを利用すれば、モデル内に書けます。
モデルクラスに直接記載すれば、グローバルスコープクラスを作成したのと同じ結果が得られます。
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* モデルの「起動」メソッド
*
* @return void
*/
protected static function booted()
{
static::addGlobalScope('ancient', function (Builder $builder) {
$builder->where('updated_at', '<', now());
});
}
}
ローカルスコープ
scopeを呼び出す際は、scopeという文字は入力せず、モデルにscope以降のメソッド名を入力します。
モデル上に下記のような感じでscope<スコープ名>でメソッドを作成します。
public function scopeSupportOn($query)
{
return $query->where('support_id', 1);
}
// void
public function scopeSupportOn($query)
{
$query->where('support_id', 1);
}
取得は下記の様にします。
Item::SupportOn();
// 大文字小文字区別されません。どちらも取得できます。
Item::supportOn()
Item::supporton()
// もちろんメソッドチェーンでも利用できます。
$items = Item::SupportOn()->orderBy('created_at')->get();
引数を渡す場合は、下記の様にします。
public function scopeSupport($query, $supportId)
{
return $query->where('support_id', $supportId);
}
取得はこうです。
$items = Item::Support(1)->get();