【laravel】orderbyをデフォルトで常に設定する方法

製作 プログラム

最終更新日:2024/09/04

ラムネグから一言:寝る前に読むとくだらなすぎて逆に寝れると好評なすごい適当なブログをこっちではじめてます.

laravelで開発していて、よく思うのが「orderbyとかwhereとか毎回書く内容同じだから、もうデフォルトで常にその処理有効にできないかな」というコトだと思います。というか私はずーっとこれ思っていました。

Modelでリレーションを書く時はhasManyとかの後に、orderbyとかwhereとかを書いて、その関係するテーブルの取得条件をデフォルトで書けるんですが、本体?というのかそのままそのModelのクエリで書くときはどうやればいいんだろうって。

その答えを今日知った(遅すぎですよね…)のですが、その名も、「グローバルスコープ」!

ここではlaravelでorderbyやwhereをデフォルトで設定できる「グローバルスコープ」について紹介しますね。

グローバルスコープの設定方法

とりあえず「こうすればもうすぐにorderbyとかwhereをデフォルトで常に(何も書かなくても)設定できるよ!」っていうのを書いて、その後にグローバルスコープとは、という話をしていきますね。

Model内に以下を追記


   protected static function booted()
    {
        static::addGlobalScope('honyarara', function (Builder $builder) {
            $builder->orderby('created_at', 'DESC');
        });
    }

この中でコピペじゃなくて実際に変更してもいい個所は「honyarara」という部分と4行目の部分だけ。それ以外はすべてまるっとコピーしてそのまま使ってください(「honyarara」については後述)。

例えばこれを「app/Models/User.php」に追記すると、今後コントローラーのどこでuserを取得する場合でも、デフォルトで並び順がcreated_atの降順になります。

例ではorderbyだけですが、ここにwhereで何かしらの絞り込み条件を書けば、それも同じように今後コントローラーでuserを取得する際、何も書かなくてもその絞り込み条件が有効になります。

つまり、毎回こう書いてたのが…

$users = User::orderby("created_at", "DESC")->get();

こうなる!

$users = User::get();
例中の「honyarara」について

例の中でaddGlobalScopeの第1引数で「honyarara」って書いてます。

これは「何でもいい」です。好きに命名してくださいね。

やってることはこのグローバルスコープに名前を付けてる個所で、この名前は「今回ばかりはこのorderbyやwhere無効にしたいな…」というときに使います。

コントローラーでこう書くとデフォルト設定が無効に!

$posts = User::withoutGlobalScope("honyarara")->get();

それ以外だとたぶん使わないんで本当に好きな前でオッケーです。

グローバルスコープとは

実装方法ももう書いたので、ここから先は「グローバルスコープとは?」というお話の部分に入っていきます。気になる人だけ読んでみてくださいね。

まずなんですが、一般的にプログラミングをしているとグローバルスコープっていうのは大域変数の事で、どこでもその値を参照できるやつ、っていう意味合いが強いのかな、と思います。というか私はそういうイメージでした。

laravelにおけるグローバルスコープっていうのはメディアクエリを作る時に、いっつも有効になるやつがグローバルスコープ、んで、まだ説明してませんが予めModelファイルに書いておいて使いたい時はコントローラー上でも「このルール使うよ!」って明示的に記述することで有効になるローカルスコープっていうのがあるんです。

そういう意味では、こちらの意味合いでもグローバル感は一応ありますよね。どんなときにも有効、っていう。対してローカルスコープの方も局所的に使うっていう意味ですごいローカル感醸し出してますよね。

んでローカルスコープについてなんですが、実はModelファイル内にはいろんなクエリの組み合わせを自分で関数作って作っておくことができて、それをローカルスコープって呼びます。んでこのローカルスコープをコントローラーで呼び出せば、コントローラーにwhereをたくさん書いたりしなくてよくなって可読性が上がる、みたいな。

毎回デフォルトで設定したいならグローバルスコープ、んで毎回じゃなくて時々呼び出すクエリなんだけどそれを1か所で管理したいならローカルスコープって感じ。ただ実際には私はローカルスコープを作るんじゃなくてコントローラーの方にずらずらと条件書いちゃってますが…。

まとめ

ここではlaravelでorderbyやwhereなどをデフォルトで設定する便利な機能「グローバルスコープ」について紹介しました。

なんというかググってもあんまり出てこなかったというか、たぶん「orderbyやwhereを常にデフォルトで設定」という検索とグローバルスコープっていう単語が結びつかな過ぎてこれまで回答に行きつけなかったんだと思います。

グローバルスコープって名前じゃなくて、orderbyデフォルト機能、みたいなのだったらすぐ公式ドキュメントなり誰かのブログなりでやり方わかってたかなーと思います。

【おしらせ、というか完全なる宣伝】

文体がもうぜんぜん適当すぎてあれだけどものすごい自由に書いてるブログ「檸檬だくだく」もよろしく.寝る前に読める恐ろしくくだらないやつです.

こんなにも一ミリも目を引かれないタイトルを取り扱ってます: ココア20g / ハイチュウとかってさ / なぜ米と小麦を食べようと思ったのかの謎 /