Laravel est un framework PHP open source et facile à utiliser. L’une de ses fonctionnalités les plus puissantes est Eloquent, un mappeur objet-relationnel (ORM) qui simplifie le traitement des enregistrements dans les bases de données.

Eloquent accélère les opérations de création, de lecture, de mise à jour et de suppression d’une base de données à partir d’une application. Lorsque vous utilisez Eloquent, vous créez des modèles qui reflètent les tables de la base de données et vous utilisez ces modèles pour créer vos requêtes.

Cet article examine six éléments de la fonctionnalité la plus puissante d’Eloquent : les champs d’application des requêtes, les relations, les mutateurs et les accesseurs, les collections, la suppression des modèles et les usines. Il décrit le rôle de chaque fonctionnalité à l’aide d’exemples pratiques. Nous espérons que vous pourrez utiliser ces exemples pour démarrer votre maîtrise de Laravel Eloquent.

1. Portée des requêtes Eloquent

Lorsque vous construisez une application, vous rencontrez parfois des situations où vous utilisez des conditions plus d’une fois. Réécrire le code dans chaque cas peut augmenter le risque d’erreurs et rendre votre code désordonné. Laravel résout ce problème en enveloppant ces conditions dans des déclarations réutilisables appelées portées ou scopes.

Les scopes de requête sont des méthodes permettant d’ajouter la logique de la base de données à un modèle et de réutiliser la logique de la requête.

Vous trouverez ci-dessous un exemple de champ d’application de requête. Supposons que vous souhaitiez créer une plateforme de développement de logiciels pour votre équipe, qui assure le suivi des fonctionnalités achevées et en cours. Vous pouvez utiliser cette condition pour récupérer uniquement les fonctionnalités en cours :

$onGoing = Project::where('ongoing', 1)->get();

Vous pouvez avoir besoin de cette condition sur d’autres pages de l’application, telles que la page des statistiques. Les champs de requête permettent à une page de réutiliser la condition ci-dessus, ce qui simplifie votre requête et rend votre code plus propre.

Voici comment vous pouvez utiliser une portée de requête pour ce scénario :

class Features extends Model
{
    public function scopeOngoing($query)
    {
        return $query->where('ongoing', 0);
    }
}

Utilisez ensuite le code ci-dessous pour exécuter cette portée :

$onGoing = Feature::ongoing()->get();

Il existe deux types de champs d’application : les champs d’application globaux et les champs d’application locaux.

Portées globales

Les portées globales permettent d’ajouter des contraintes à toutes les requêtes d’un modèle. Par exemple, vous pouvez ajouter une condition pour filtrer les caractéristiques en fonction du nom du chef d’équipe dans toutes les requêtes de votre modèle.

Portées locales

Les champs d’application locaux permettent de définir des contraintes communes à des fins de réutilisation. Par exemple, vous pouvez vouloir que l’application renvoie les caractéristiques qui ont des bogues. Votre code pourrait mettre en œuvre une portée locale comme suit :

namespace AppModels;
use IlluminateDatabaseEloquentModel;

class User extends Model
{
    public function scopeBugged($query)
    {
        return $query->where('bugged', '>', 1);
    }
}

Le code ci-dessus renvoie toutes les fonctionnalités qui ont des bogues non corrigés.

2. Relations Eloquent

Les relations dans Eloquent vous permettent de relier facilement différentes tables. Par exemple, un produit sur un site de commerce électronique peut avoir un inventaire, un prix, des vues et des commentaires. Avec Eloquent, vous pouvez facilement gérer ces relations même si leurs enregistrements se trouvent dans des tables différentes.

Vous pouvez définir les relations comme des méthodes sur les classes de modèle, tout comme vous le feriez pour un modèle Eloquent. Parmi les relations Eloquent couramment utilisées, citons les relations univoques, inverses et polymorphes.

Un à un

Voici un exemple de relation univoque de base qui associe un modèle de produit à un inventaire.

public function Inventory()
{
    return $this->hasOne('AppInventory');
}

Dans le code ci-dessus, la méthode Inventory() appelle la méthode hasOne() sur le modèle de produit. Cette méthode vérifie si le produit est actuellement disponible.

Inverse

Eloquent vous permet également de créer une relation inverse. Par exemple, lorsque vous souhaitez récupérer des produits en fonction de leur nombre de vues. Les relations inverses peuvent vous donner les produits qui suscitent le plus d’intérêt de la part des visiteurs d’un site web. Vous pouvez utiliser la méthode belongsTo(), qui est l’inverse de hasOne(). Le code ci-dessous l’illustre.

public function product()
{
    return $this->belongsTo('AppProduct');
}

Dans le code ci-dessus, Eloquent fait correspondre le product_id au nombre de vues transmises. Le product_id peut alors aider à récupérer d’autres paramètres, tels que le prix et l’inventaire.

Polymorphe

Dans le développement d’applications, les relations ne sont pas toujours simples. Parfois, vous avez un modèle qui appartient à plus d’un type de modèle. Par exemple, les modèles de produit et d’inventaire peuvent tous deux avoir des relations polymorphes avec un modèle d’image.

Les relations polymorphes vous permettent d’utiliser la même liste d’images pour l’inventaire et les produits. Vous trouverez ci-dessous un extrait de code mettant en œuvre une relation polymorphe.

class Image extends Model
{
    /**
     * Getting the shared image.
     */
    public function myimage()
    {
        return $this->morphTo();
    }
}

class Product extends Model
{
    /**
     * Get the image to use on the product's page.
     */
    public function image()
    {
        return $this->morphOne(Image::class, 'myimage');
    }
}

class Inventory extends Model
{
    /**
     * Get the image to use on the inventory page.
     */
    public function image()
    {
        return $this->morphOne(Image::class, 'myimage');
    }
}

Le code ci-dessus utilise la méthode morphTo() pour récupérer le parent du modèle polymorphe.

Ce n’est que la partie émergée de l’iceberg sur ce sujet. Pour en savoir plus, consultez notre guide avancé sur les relations Laravel Eloquent.

3. Mutateurs et accesseurs Eloquent

Les mutateurs et les accesseurs vous permettent de modifier les données tout en les stockant et en les récupérant. Les mutateurs modifient les données avant de les enregistrer, tandis que les accesseurs les modifient lors de leur récupération.

Si vous souhaitez stocker les noms en minuscules dans votre base de données, vous pouvez créer un mutateur pour exécuter cette transformation. Si vous souhaitez afficher le prénom et le nom de l’utilisateur en un seul nom sur les pages de votre application, vous pouvez créer un accesseur pour y parvenir.

Vous trouverez ci-dessous un exemple de mutateur qui met les noms en majuscules avant de les enregistrer.

class User extends Model
{
    /**
     * Mutators capitalizing first and last name.
     */
    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = ucfirst($value);
    }

    public function setLastNameAttribute($value)
    {
        $this->attributes['last_name'] = ucfirst($value);
    }
}

Vous trouverez ci-dessous un exemple d’accesseur qui combine le prénom et le nom de l’utilisateur.

class User extends Model
{
    /**
     * Accessor combining both names.
     */
    public function getFullNameAttribute()
    {
        return ucfirst($this->first_name) . ' ' . ucfirst($this->last_name);
    }
}

4. Collections Eloquent

Les collections Eloquent gèrent les méthodes qui renvoient plusieurs résultats de modèles. Cette classe se trouve à l’adresse IlluminateDatabaseEloquentCollection.

Comme pour les tableaux, il est possible d’itérer dans les collections. Vous trouverez ci-dessous une itération simple.

use AppModelsProduct;

$products = Product::where('availability', 1)->get();

foreach ($products as $product) {
   echo $product->name;
}

Les collections sont plus puissantes que les tableaux, car elles permettent d’effectuer des opérations plus complexes. Par exemple, vous pouvez afficher la liste de tous les produits disponibles et ignorer tous ceux qui ne sont pas « actifs »

$names = Product::all()->reject(function ($product) {
   return $product->active === false;
})->map(function ($product) {
   return $product->name;
});

Vous trouverez ci-dessous quelques-unes des méthodes proposées par la classe des collections.

Contient

La méthode contains() vérifie si le code contient un mode spécifié, comme le montre le code ci-dessous :

$products->contains(1);
$products->contains(Product::find(1));

All

La méthode all() renvoie les modèles contenus dans la collection, comme indiqué ci-dessous :

$collection = Product::all();

De nombreuses autres méthodes sont prises en charge par la classe collections.

5. Supprimer des modèles Eloquent

Dans Eloquent, vous créez des modèles pour vous aider à construire des requêtes. Cependant, il est parfois nécessaire de supprimer des modèles pour rendre une application plus efficace. Pour cela, appelez delete sur l’instance du modèle.

use AppModelsStock;

$stock = Stock::find(1);
$stock->delete();

Le code ci-dessus supprime le modèle Stock d’une application. Il s’agit d’une suppression permanente qui ne peut être annulée.

Suppression en douceur

Une autre fonctionnalité d’Eloquent est la possibilité de supprimer un modèle en douceur. Lorsque vous supprimez un modèle, vous ne le supprimez pas de la base de données.

Vous le marquez en utilisant deleted_at pour indiquer l’heure et la date de l’effacement. Cette fonction est importante lorsque vous souhaitez exclure une partie des enregistrements de la base de données, tels que ceux qui sont incomplets, sans les supprimer définitivement. Elle permet de nettoyer les résultats des requêtes d’Eloquent sans ajouter de conditions supplémentaires.

Vous activez la suppression douce en ajoutant le trait softDeletes à un modèle et en ajoutant une colonne deleted_at à la table de base de données correspondante.

Ajout de la suppression douce à un modèle

Vous activez les suppressions douces dans un modèle en ajoutant le trait IlluminateDatabaseEloquentSoftDeletes, comme illustré ci-dessous.

namespace AppModels;
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentSoftDeletes;

class Flight extends Model
{
   use SoftDeletes;
}

Comment ajouter une colonne delete_at

Avant de pouvoir utiliser l’effacement progressif, votre base de données doit comporter une colonne delete_at. Vous ajoutez cette colonne à l’aide d’une méthode Laravel Schema builder helper, comme indiqué ci-dessous :

use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;

Schema::table('users', function (Blueprint $table) {
   $table->softDeletes();
});

Schema::table('users', function (Blueprint $table) {
   $table->dropSoftDeletes();
});

Cette méthode ajoute une colonne delete_at qui est mise à jour avec la date et l’heure, dans le cas d’une action de suppression douce réussie.

Comment inclure les modèles supprimés

Si vous souhaitez que les résultats de la requête incluent les modèles supprimés à l’amiable, vous devez ajouter la méthode withTrashed() à la requête. Un exemple est présenté ci-dessous :

$stocks = Stock::withTrashed()->where('stock_id', 20)->get();

La requête ci-dessus inclura également les modèles avec l’attribut deleted_at.

Comment récupérer uniquement les modèles supprimés par voie électronique ?

Eloquent vous permet également de récupérer exclusivement les modèles supprimés. Vous pouvez le faire en appelant la méthode onlyTrashed(), par exemple :

$Stock = Stock::onlyTrashed()->where('stock_id', 1)->get();

Comment restaurer des modèles supprimés

Vous pouvez également restaurer des modèles supprimés en appelant la méthode restore().

$stocks = Stock::withTrashed()->where('stock_id', 20)->restore();

Cette méthode remplace le champ delete_at d’un modèle supprimé par défaut par le champ null. Si le modèle n’a pas été supprimé, le champ reste inchangé.

6. Usines Eloquent

Les usines de modèles de Laravel créent des données fictives que vous pouvez utiliser pour tester votre application ou pour alimenter votre base de données. Pour cela, vous devez créer un modèle dans une classe de fabrique, comme le montre l’exemple ci-dessous. L’extrait de code crée une fabrique de modèles qui peut générer de faux fournisseurs d’un produit et de ses prix.

namespace DatabaseFactories;
use IlluminateDatabaseEloquentFactoriesFactory;
use IlluminateSupportStr;

class StockFactory extends Factory
{
    public function definition()
    {
        return [
            'supplier_name' => fake()->name(),
            'price' => fake()->numberBetween($min = 1500, $max = 6000),
        ];
    }
}

La méthode definition() dans l’exemple ci-dessus renvoie un ensemble de valeurs d’attributs que Laravel utilise lors de la construction du modèle. L’aide à la création de faux permet à la fabrique d’accéder à la bibliothèque PHP Faker.

En résumé

Eloquent simplifie les tâches de développement d’applications dans Laravel. Il est aussi efficace pour construire des requêtes simples que complexes, grâce à des implémentations telles que les relations. La simplicité de génération de données factices fonctionnelles à l’aide de factories le rend parfait pour les développeurs qui veulent créer des tests robustes pour leurs applications. De plus, les scopes d’Eloquent aident à simplifier les requêtes complexes d’une manière qui laisse le code propre.

Bien que cet article n’ait couvert que six de ses principales caractéristiques, Eloquent possède d’autres fonctionnalités puissantes. L’utilisation de modèles partageables et réutilisables a fait d’Eloquent une fonctionnalité populaire parmi les développeurs, et la simplicité des requêtes Eloquent fait de Laravel un framework convivial pour les développeurs, même pour les débutants.

Quel que soit votre niveau d’expérience, la plateforme d’hébergement d’applications web de Kinsta soutient les développeurs comme vous. Notre modèle de démarrage rapide Laravel montre à quel point il est facile de mettre en place votre application et de la faire fonctionner sur nos serveurs au sein du réseau premium de Google Cloud.

Steve Bonisteel Kinsta

Steve Bonisteel is a Technical Editor at Kinsta who began his writing career as a print journalist, chasing ambulances and fire trucks. He has been covering Internet-related technology since the late 1990s.