【Laravel】グローバルスコープの使い方と意味について



1. グローバルスコープとは
Laravelのグローバルスコープは、クエリに自動的に条件を適用する仕組みです。たとえば、is_deleted
フラグがfalse
のデータだけを取得したい場合や、特定のユーザーに関連するデータのみを常にフィルタリングしたい場合に便利です。
1.1. グローバルスコープの基本
通常、Eloquentを使用してクエリを作成するとき、必要に応じて条件を追加します。以下の例を見てください。
// 条件を指定してデータを取得
$users = User::where('is_active', true)->get();
しかし、どのクエリでも同じ条件(ここではis_activeがtrue)を適用したい場合、毎回whereを記述するのは手間ですし、書き忘れる可能性もあります。これを防ぐのがグローバルスコープの役割です。
グローバルスコープを設定することで、モデルに対するすべてのクエリに指定した条件が自動で適用されます。
1.2. Laravelの動作環境
Laravelを利用する環境は基本的に、次の通りです。
- Laravel Framework 10.48.25
- php 8.1
2. グローバルスコープの実装方法
ここでは、記事の公開状態を管理する例を使って、グローバルスコープの設定手順を説明します。
2.1. Articleモデルとデータ
まず、articles
テーブルが以下のような構造を持っていると仮定します。
id | title | content | status | created_at | updated_at |
---|---|---|---|---|---|
1 | 初めての記事 | サンプル本文 | draft |
2024-12-01 10:00:00 | 2024-12-01 10:00:00 |
2 | 非公開の記事 | 非公開本文 | draft |
2024-12-02 12:00:00 | 2024-12-02 12:00:00 |
3 | 公開済みの記事 | 記事本文 | published |
2024-12-03 15:00:00 | 2024-12-03 15:00:00 |
グローバルスコープを利用して、is_published
がdraft
のデータのみをデフォルトで取得するようにします。例えば、次のようにデータを表示したとします。
2.2. スコープの設定
2.2.1. スコープクラスを作成
グローバルスコープを適用するには、専用のスコープクラスを作成します。以下のコマンドを実行してスコープクラスを作成しましょう。
php artisan make:scope PublishedScope
これにより、App\Models\Scopesディレクトリ内にPublishedScopeという名前のスコープクラスが作成されます。作成されたスコープクラスに条件を追加します。
namespace App\Models\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
class PublishedScope implements Scope
{
public function apply(Builder $builder, Model $model)
{
// 非公開済みの記事のみを取得する条件
$builder->where('status', "draft");
}
}

2.2.2. Articleモデルに適用
次に、Article
モデルにこのスコープを適用します。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Scopes\PublishedScope;
class Article extends Model
{
protected static function booted()
{
// スコープを適用
static::addGlobalScope(new PublishedScope);
}
}
これで、Article::all()
やArticle::where()
を使用すると、status = "draft"
の条件が自動的に適用されます。ここで使用したbooted
メソッドは、Eloquentモデルで初期設定を行うための静的メソッドです。このメソッドは、モデルが初めて「ブート」されるときに呼び出されます。ここで、モデルにグローバルスコープを追加したり、特定のイベントリスナーを登録するなど、モデル全体に適用される処理を定義できます。

booted
メソッドにスコープを適用すればOKだよ!これで、モデルに対するすべてのクエリに自動的に条件がつく!2.3. コントローラーでデータ取得
次に、コントローラーを作成してデータを取得します。
php artisan make:controller ArticleController
以下のようにデータを取得してビューに渡します。
namespace App\Http\Controllers;
use App\Models\Article;
class ArticleController extends Controller
{
public function index()
{
// グローバルスコープにより公開済みの記事だけを取得
$articles = Article::orderBy('created_at', 'desc')->get();
return view('articles.index', compact('articles'));
}
}
2.4. 実行結果
ブラウザでこのページを表示すると、以下のようなテーブルが表示されます。
非公開の記事のみ表示することができました。
2.5. スコープの一時無効化
必要に応じてスコープを無効化して全データを取得する場合、以下を使用します。
use App\Models\Scopes\PublishedScope;
$articles = Article::withoutGlobalScope(PublishedScope::class)->get();