見出し画像

Laravel学習記録 #038 クエリスコープを学ぶ

Laravelのスコープについて学習したことをまとめております。

クエリスコープとは

  • Eloquent ORMを使用してクエリを再利用可能にするための機能

  • ローバルスコープとローカルスコープの2種類がある

  • グローバルスコープは特定のモデルに対する全てのクエリに適用

  • ローカルスコープは明示的に呼び出されたクエリにのみ適用


グローバルスコープ

特定のモデルに対する全てのクエリに適用することができる。

スコープクラスを作成
Illuminate\Database\Eloquent\Scopeインターフェイスの実装クラスを定義

namespace App\Models\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;

class AncientScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        $builder->where('created_at', '<', now()->subYears(2000));
    }
}

モデルのbootedメソッドで適用

namespace App\Models;

use App\Models\Scopes\AncientScope;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected static function booted()
    {
        static::addGlobalScope(new AncientScope);
    }
}


匿名のグローバルスコープとして定義することもできる
その場合、モデルでクロージャを使用して定義する

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected static function booted()
    {
        static::addGlobalScope('ancient', function (Builder $builder) {
            $builder->where('created_at', '<', now()->subYears(2000));
        });
    }
}


ローカルスコープ

明示的に呼び出されたクエリにのみ適用できて汎用性が高い

定義
対象モデルにスコープメソッドを定義します。
命名規則としてメソッド名の前にscopeを付けます。

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function scopePopular($query)
    {
        return $query->where('votes', '>', 100);
    }

    public function scopeActive($query)
    {
        $query->where('active', 1);
    }
}


パラメータを受け入れるスコープも定義する場合は
引数にパラメータを追加します。

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function scopeOfType($query, $type)
    {
        return $query->where('type', $type);
    }
}

$users = User::ofType('admin')->get();


使う
ローカルスコープは命名したscopeプレフィックスを除いて呼び出します。

use App\Models\User;

$users = User::popular()->active()->orderBy('created_at')->get();



今回は以下を読んだだけなので、また試してみたいと思います。
https://readouble.com/laravel/10.x/ja/eloquent.html


この記事が気に入ったらサポートをしてみませんか?