更新:2024/12/05

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

はるか
はるか
ローカルスコープって便利。クエリがすっきりする。
ふゅか
ふゅか
Laravelでは、よく使うクエリを簡単に再利用できる仕組みの一つだよね!

1. ローカルスコープ

Laravelには、クエリビルダEloquentを使ったデータベース操作を簡単にするための便利な機能が多数用意されています。その中でも「ローカルスコープ」は、特定の条件でデータを取得するクエリを再利用可能にする便利な仕組みです。この記事では、Articleモデルを例に、ローカルスコープの基本的な使い方やその利点をわかりやすく解説します。

1.1. ローカルスコープとは?

ローカルスコープは、Eloquentモデルにおいて、クエリ条件をメソッドでモデル内に定義する方法です。例えば、公開された記事(公開ステータスがpublishedのもの)だけを取得するクエリを頻繁に使う場合、ローカルスコープを定義することで、簡潔で再利用可能な形にできます。

1.2. Laravelの動作環境

Laravelを利用する環境は基本的に、次の通りです。

  • Laravel Framework 10.48.25
  • php 8.1

2. ローカルスコープの作り方

ローカルスコープは、Eloquentモデル内で「scope」という接頭辞を使ったメソッドとして定義します。

はるか
はるか
クエリ条件をモデルに定義する。scopeを使う。
ふゅか
ふゅか
そう!例えば、scopePublished って名前で「公開記事」専用のスコープを作れるよ。メソッド名は「scope+任意の名前」で始めるんだ。

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

例えば、次のようにデータを表示したとします。

2.2. Articleモデルでローカルスコープを定義する

例えば、「公開中の記事(published status)」を取得するローカルスコープをArticleモデルに追加します。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    // ローカルスコープの定義
    public function scopePublished($query)
    {
        return $query->where('status', 'published');
    }
}

メソッド名は scopePublished としますが、クエリ実行時には Published 部分だけを使います。
$query は、クエリビルダのインスタンスを受け取る引数です。

2.3. スコープを使ったクエリの記述

ローカルスコープを使用する場合は、scopeの接頭辞を省略して呼び出します。

use App\Models\Article;

// ローカルスコープを適用して公開中の記事を取得
$publishedArticles = Article::published()->get();

このコードは、次のようなクエリを記述するのと同じ意味です。

$publishedArticles = Article::where('status', 'published')->get();

3. ローカルスコープに引数を追加する

ローカルスコープは、引数を取ることができます。これにより、条件を柔軟に設定できます。

はるか
はるか
引数も渡せる。
ふゅか
ふゅか
そうだね!例えば、「タイトルに特定の文字を含む記事を取得」したいときは、引数を取るスコープを作るといいよ!

3.1. 引数を持つローカルスコープの定義

例えば、特定のカテゴリの記事を取得するローカルスコープを定義します。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    // 引数を持つローカルスコープ
    public function scopeTitle($query, $title)
    {
        return $query->where('title','LIKE', "%".$title."%");
    }
}

3.2. スコープに引数を渡してクエリを実行

以下のように呼び出して、引数を指定します。

use App\Models\Article;

// Laravelをタイトルに含む記事を取得
$articles = Article::title("Laravel")->get();

4. 複数のローカルスコープを組み合わせる

ローカルスコープは、メソッドチェーンとして組み合わせることができます。

4.1. 例: 公開中かつ特定のタイトルを含む記事を取得

以下のように複数のスコープをチェーンでつなげます。

use App\Models\Article;

// Laravelをタイトルに含む公開中の記事を取得
$publishedTechArticles = Article::published()->title('Laravel')->get();

これにより、柔軟なクエリも簡潔に書けるようになります。

5. スコープの例

例えば、記事の「公開日順で並び替え」や「特定の日付以降の記事を取得する」スコープも作成できます。

5.1. 公開日順に並び替えるスコープ

public function scopeRecent($query)
{
    return $query->orderBy('published_at', 'desc');
}

5.2. 日付以降の記事を取得するスコープ

public function scopeFromDate($query, $date)
{
    return $query->where('published_at', '>=', $date);
}
PR