ホーム » クエリスコープの利用方法について

クエリスコープの利用方法について

クエリスコープとは?

クエリスコープ(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();