21 octobre 2021 173.641K

Formation Laravel : Scopes, Accessors, Mutators

1. Les Scopes

Vous pouvez être amené à faire assez souvent les mêmes requêtes. Cela peut vite devenir fastidieux de devoir écrire à chaque fois les mêmes morceaux de codes et tout le monde sait qu’un développeur n’aime pas se répéter ! ^^

Local Scopes

Il vous est donc possible, grâce à Eloquent, de créer des scopes dans vos Models afin de définir des query builder spécifique.

Imaginons par exemple que je doive fréquemment récupérer depuis ma base de données les livres par prix ascendant :

$books = Book::where('author', $author)->orderBy('price', 'ASC')->get();

Je décide donc de faire un scope local dans mon Model Book :

public function scopeAscPriceOfAuthor($query, $author) {
    return $query->where('author', $author)->orderBy('price', 'ASC');
}

Je nomme donc ce scope “scopeAscPriceOfAuthor” (garder bien ça en tête pour la suite ^^) et je passe à cette méthode 2 paramètres :
$query : il s’agit du paramètre obligatoire à passer pour qu’Eloquent comprenne de quelle requête il s’agit.$author : ce paramètre permet de faire des scopes dynamiques. On voit qu’ici nous devons déterminer un auteur pour notre Query Builder, ce deuxième paramètre permet de faire passer l’info à notre scope. 😉

Maintenant dans notre Controller il nous suffit d’écrire :

$books = Book::ascPriceOfAuthor(1)->get();

On remarque ici que pour faire appel à notre scope on skip ‘scope’ dans le camelKey : ascPriceOfAuthor. Et on passe en paramètre notre valeur dynamique ($author qui est ici en relation avec la table author via la colonne id, donc il s’agit d’un id).

Global Scopes

Les scopes que nous venons de voir sont des Local Scopes, mais vous pouvez également créer des Global Scopes applicables de manière globale dans toutes les Query Builders de votre Model. Pour l’exemple je vais créer un scope global pour qu’à chaque Query Builder il faille que la valeur de la colonne ‘author’ soit supérieur à 0 (oui dans la pratique ce cas est un peu bizarre et peu paraître stupide mais c’est pour l’exemple ^^).

Nous allons donc créer une nouvelle class pour notre Global Scope que l’on placera dans un dossier que l’on créera (app/scopes) :

<?php 

namespace App\Scopes;

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class AuthorScope implements Scope
{

    public function apply(Builder $builder, Model $Book) 
    {
        $builder->where('author', '>', 0);
    }

}

Maintenant il faut déclarer à notre Model Book cette nouvelle scope globale :

protected static function boot() {
    parent::boot();

    static::addGlobalScope(new AuthorScope);
}

Maintenant pour chacune de nos Query Builders cette scope globale sera appliquée.

Si vous avez besoin de retirer cette scope globale pour une requête précise vous pouvez utiliser la méthode withoutGlobalScope() :

$books = withoutGlobalScope(AuthorScope::class)->get();

2. Les Accessors

Les accessors vous permettent d’ajouter de nouveaux getters. Pour l’exemple nous allons prendre notre Class Author, nous avons une colonne ‘firstname’ pour le prénom de l’auteur et une colonne ‘lastname’ pour son nom de famille. Pour accéder à ces valeurs depuis un auteur récupéré nous faisons $author->firstname et $author->lastname.

Maintenant imaginons que nous voulons un getter ‘fullname’ pour le nom complet de cette auteur. Cela est possible avec nos deux variables :

$fullname = $author->firstname.' '.$author->lastname;

Créer un accessor va nous permettre de l’écrire directement comme ça :

$author->fullName;

Pour cela il suffit simplement de créer un accessor dans la Class de notre model Author :

public function getFullNameAttribute() {
    return $this->firstname.' '.$this->lastname;
}

Pour créer un accessor le nom de la méthode doit respecter la nomenclature suivante : get+sonNom+Attribute et pour y accéder il suffit de faire $obj->sonNom.

Dans notre exemple donc, pour accéder à l’accessor créé il suffit de faire :

$author->fullName;

3. Les Mutators

Les Mutators, eux, sont des setters. Ils suivent la même logique de nomenclature que les accessors mais avec ‘set’ devant :

set+sonNom+Attribute. Prenons un autre exemple rapide simplement pour illustrer : nous voulons créer un setter pour les prix de nos livres :

public function setPriceAttribute($value) {
    $this->attributes['price'] = $value.' €';
}

Maintenant lorsque l’on va entrer une valeur pour le prix de l’un de nos livres ce prix sera succédé par le symbole euro :

$book->price = 12;
// ici $book->price retournera '12 €'

Laravel permet également de gérer les Dates Mutators en convertissant des colonnes en instance de Carbon. Les colonnes de temps que l’on trouve par défaut lors de la création d’une table (created_at et updated_at) sont automatiquement converties en Carbon. Si vous voulez préciser à Laravel d’autres colonnes de date à convertir en Carbon il faut lui définir ces colonnes dans un tableau $dates. Reprenons notre table Author où nous avons 2 colonnes de date (birth et death) :

protected $dates = [
    'birth', 'death'
];

Il vous est maintenant possible d’accéder à des méthodes de Carbon pour ces valeurs pour par exemple afficher cette date dans un format particulier :

$author->birth->format('d.m.Y H:i');

Par défaut les timestamps sont formatés comme ceci : 'Y-m-d H:i:s' dans votre base de données. Mais vous pouvez décider de déterminer dans votre model un format de date lors de l’enregistrement de vos dates dans votre base de données :

protected $dateFormat = 'm.Y';

Besoin d'une formation personalisée ?

Avis

4,9
Rated 4.9 out of 5
Excellent88%
Splendide !12%
Sympa0%
Sans plus0%
Pas terrible0%

Pas de titre

Rated 5 out of 5
15 avril 2024

cool

paul

Pas de titre

Rated 5 out of 5
2 avril 2024
Evelyn

Pas de titre

Rated 4 out of 5
2 avril 2024

Merci beaucoup pour ce cour.

adil

Pas de titre

Rated 5 out of 5
7 mars 2024

super

hajar

Pas de titre

Rated 5 out of 5
21 juin 2023

Merci énormément je suis sur exciter à cause de ce cours

Kassi Patrick