Help us understand the problem. What is going on with this article?

【Laravel】毎回同じ検索条件を書くならEloquentのクエリスコープを使う

3年弱Laravelを使っていたのに、今まで存在を知らなかった便利な機能「クエリスコープ」を使ってみました。

こんなケース

ブログサイトを作っていたとして、記事データを取得する機会って結構あると思います。

  • 検索結果を表示する時
  • 記事の詳細を表示する時
  • 最近の記事を表示する時
  • 関連する記事を表示する時

仕様によっては、まだまだあると思います。

そんな時、おきまりの様に毎回指定する条件があったりします。

  • ステータスコードが「公開」である
  • 画面表示日時が公開日時に含まれている

これを検索のたびに毎回書くのってなんか嫌ですよね。
そこで登場するのがクエリスコープです。

クエリスコープ

クエリスコープには

  • Eloquentモデルを使うと勝手に条件が追加されるグローバルスコープ
  • 条件を一つのメソッドにまとめて、条件を追加したい時にだけ使うローカルスコープ

があります。

今回は、過去のブログを取得したいケースを想定して、ローカルスコープを使ってみます。
グローバルスコープについては公式ページとか日本語サイトを見てみてください。

ローカルスコープの定義

ローカルスコープの場合、使いたいモデルにscopeという文字を頭につけたメソッド名を定義する。

Blog.php
<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Blog extends Model
{
    use SoftDeletes;

    /**
     * 公開中の条件
     *
     * @param $query
     * @return mixed
     */
    public function scopeOpen($query){
        return $query->where('status', 1)
            ->whereDate('start_at', '<=', Carbon::today())
            ->whereDate('end_at', '>=', Carbon::today());
    }
}

使い方

使うときはこんな感じ。scopeを取り除いたメソッド名で呼び出す。

public function getBlogsOrderByStartAtDesc(){
        return Blog::query()->open()
            ->orderBy('start_at', 'desc')
            ->get();
}

今まで知らなくて同じ様な条件をいっぱい書いていた気がします。
これを使えば、条件の書き忘れもないし、仕様変更で条件を変える時もここだけ直せば良いので便利です。

ただ、便利な分なんでもできてしまいますが、クエリスコープのメソッド内では単純な条件追加だけにしておいて、if文などの複雑なロジックは書かない方がいいと思われます。
処理が追いにくくなったり、メソッド名と処理内容が乖離してしまったりして事故の元になるので。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away