Maison > développement back-end > tutoriel php > Générateurs de requêtes personnalisées Laravel sur les étendues

Générateurs de requêtes personnalisées Laravel sur les étendues

Barbara Streisand
Libérer: 2024-11-28 05:37:18
original
983 Les gens l'ont consulté

Laravel Custom Query Builders Over Scopes

Bonjour ?

Très bien, parlons des étendues de requête. Ils sont géniaux, ils rendent les requêtes beaucoup plus faciles à lire, cela ne fait aucun doute. Mais il y a une chose que je déteste chez eux : la magie. Et lorsque vous travaillez avec une équipe où tout le monde n’est pas développeur back-end, cela peut leur rendre la vie misérable. Bien sûr, vous pouvez ajouter des PHPDocs, mais il y a toujours un peu de magie à l'œuvre. Si vous n'avez jamais utilisé de lunettes auparavant, ne vous inquiétez pas, accrochez-vous bien.

Alors, que sont les portées ? ?

Considérez ce code :

use App\Models\User;

$users = User::query()
    ->where('votes', '>', 100);
    ->where('active', 1);
    ->orderBy('created_at')
    ->get();
Copier après la connexion

C'est ainsi que vous écrivez généralement des requêtes. Mais lorsque les requêtes deviennent trop complexes ou difficiles à lire, vous pouvez les résumer dans des étendues :

<?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);
    }
}
Copier après la connexion

Maintenant, vous pouvez faire ceci :

$users = User::query()
    ->popular()
    ->active()
    ->orderBy('created_at')
    ->get();
Copier après la connexion
Copier après la connexion

Ça se lit beaucoup mieux, non ? Je sais. Mais le problème est que vous n’obtenez aucune saisie semi-automatique. C'est de la magie noire pour l'IDE. Étant donné que les étendues sont résolues au moment de l'exécution et préfixées par scope, votre IDE ne peut en aucun cas les connaître à moins que vous ne l'aidiez.

Une solution consiste à utiliser PHPDocs, comme ceci :

/**
 * @method static Builder popular()
 * @method static Builder active()
 */
class User extends Model
Copier après la connexion

Un autre inconvénient des oscilloscopes ? Les modèles les plus fréquemment utilisés finissent par en être remplis de tonnes, pour rien. J'aime parcourir mes modèles et voir immédiatement les relations et la logique de base, pas un tas d'abstractions de requêtes.

Alors ? Devons-nous simplement abandonner les lunettes et passer à autre chose ? Eh bien, c'est une option, ou vous pouvez utiliser des générateurs de requêtes personnalisés.

Générateurs de requêtes personnalisées ?

Comme son nom l'indique, un générateur de requêtes personnalisé vous permet de déplacer toutes vos abstractions de requêtes dans une classe dédiée. Le code sera plus organisé d'une certaine manière.

Créons une nouvelle classe 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);
    }
}

Copier après la connexion

Où placer les constructeurs ? Il n'y a pas de ligne directrice, mais personnellement, j'aime les placer dans app/Eloquent/QueryBuilders.

Utilisons maintenant ce générateur dans le modèle utilisateur :

<?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();
    }
}
Copier après la connexion

Et juste comme ça, vous pouvez désormais faire :

$users = User::query()
    ->popular()
    ->active()
    ->orderBy('created_at')
    ->get();
Copier après la connexion
Copier après la connexion

Fonctionne exactement de la même manière et vous bénéficiez d'une saisie semi-automatique complète. De plus, la navigation par code fonctionne parfaitement, elle vous emmène là où vous devez être ?

Une autre chose intéressante est que vous pouvez résoudre dynamiquement les générateurs de requêtes si nécessaire.

public function newEloquentBuilder($query): UserQueryBuilder
{
    if ($this->status === State::Pending) {
        return new PendingUserQueryBuilder($query); // extends UserQueryBuilder
    }

    return new UserQueryBuilder($query);
}
Copier après la connexion

De cette façon, vous évitez d'avoir un seul gros générateur de requêtes lorsque vous pouvez regrouper les requêtes par contexte (comme un état).

C'est tout ✅

Les scopes sont cool, et si je n'en ai que 2-3, je m'en tiendrai à eux. Mais lorsque les choses commencent à devenir incontrôlables, les générateurs de requêtes personnalisées sont la solution. Ils valent l'effort supplémentaire, en gardant votre code propre, organisé et plus facile à maintenir ?

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal