それでは、クエリ スコープについて話しましょう。これらは素晴らしいもので、クエリがはるかに読みやすくなることは間違いありません。でも、彼らについて私が嫌いなことが 1 つあります。それは魔法です。また、全員がバックエンド開発者ではないチームで作業していると、チームの生活が悲惨になる可能性があります。確かに、PHPDoc を追加することはできますが、常に何らかの魔法が起こっています。これまでスコープを使用したことがなくても、心配する必要はありません。しっかりと取り組んでください。
次のコードを考えてみましょう:
use App\Models\User; $users = User::query() ->where('votes', '>', 100); ->where('active', 1); ->orderBy('created_at') ->get();
これが通常のクエリの作成方法です。ただし、クエリが複雑すぎたり、読みにくくなった場合は、クエリをスコープに抽象化できます。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; class User extends Model { public function scopePopular(Builder $query): void { $query->where('votes', '>', 100); } public function scopeActive(Builder $query): void { $query->where('active', 1); } }
これで次のことができるようになります:
$users = User::query() ->popular() ->active() ->orderBy('created_at') ->get();
読みやすくなりましたね?知っている。しかし問題は、オートコンプリートが表示されないことです。これは IDE にとっては闇の魔法です。スコープは実行時に解決され、スコープという接頭辞が付けられるため、ユーザーがサポートしない限り、IDE がスコープについて知ることはできません。
1 つの方法は、次のように PHPDoc を使用することです。
/** * @method static Builder popular() * @method static Builder active() */ class User extends Model
スコープのもう一つの欠点は?最も頻繁に使用されるモデルは、無駄に大量のモデルを搭載して肥大化してしまいます。私はモデルをざっと読んで、大量のクエリ抽象化ではなく、関係性とコア ロジックをすぐに確認するのが大好きです。
そうか?スコープを捨てて先に進むのでしょうか?まあ、それはオプションですが、カスタム クエリ ビルダーを使用することもできます。
名前が示すように、カスタム クエリ ビルダーを使用すると、すべてのクエリ抽象化を専用のクラスに移動できます。コードはある意味でより整理されます。
新しいクラス UserQueryBuilder を作成しましょう:
<?php namespace App\Eloquent\QueryBuilders; use App\Models\User; use Illuminate\Database\Eloquent\Builder; class UserQueryBuilder extends Builder { public function popular(): self { return $this->where('votes', '>', 100); } public function active(): self { return $this->where('active', 1); } }
ビルダーをどこに配置するか?ガイドラインはありませんが、個人的には app/Eloquent/QueryBuilders に配置することを好みます。
次に、このビルダーを User モデルで使用してみましょう:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; class User extends Model { public function newEloquentBuilder($query): UserQueryBuilder { return new UserQueryBuilder($query); } // for type hints public static function query(): UserQueryBuilder { return parent::query(); } }
このようにして、次のことができるようになります:
$users = User::query() ->popular() ->active() ->orderBy('created_at') ->get();
全く同じように動作し、完全なオートコンプリートが得られます。さらに、コードナビゲーションは完璧に機能し、必要な場所に移動します?
もう 1 つの優れた点は、必要に応じてクエリ ビルダーを動的に解決できることです。
public function newEloquentBuilder($query): UserQueryBuilder { if ($this->status === State::Pending) { return new PendingUserQueryBuilder($query); // extends UserQueryBuilder } return new UserQueryBuilder($query); }
この方法では、クエリをコンテキスト (状態など) ごとにグループ化できる場合に、1 つの大きなクエリ ビルダーを使用する必要がなくなります。
スコープはクールなので、2 ~ 3 個しか持っていないとしても、使い続けるつもりです。しかし、物事が手に負えなくなり始めた場合は、カスタム クエリ ビルダーが最適です。コードをクリーンで整理し、保守しやすくするため、余分な努力をする価値がありますか?
以上がスコープを介した Laravel カスタムクエリビルダーの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。