Laravel is een open-source en eenvoudig te gebruiken PHP framework. Een van de krachtigste functies is Eloquent, een object-relationele mapper (ORM) die het verwerken van databaserecords vereenvoudigt.

Eloquent versnelt het maken, lezen, bijwerken en verwijderen van gegevens uit een database vanuit een applicatie. Als je Eloquent gebruikt, maak je modellen die databasetabellen weerspiegelen en gebruik je die modellen om query’s te maken.

In dit artikel worden zes elementen van de krachtigste functionaliteit van Eloquent besproken: query scopes, relaties, mutators en accessors, collections, modelverwijdering en model factories. Aan de hand van praktische voorbeelden wordt uitgelegd wat elke functie doet. We hopen dat je deze voorbeelden kunt gebruiken om een vliegende start te maken met Laravel Eloquent.

1. Eloquent query scopes

Bij het bouwen van een applicatie kom je soms situaties tegen waarin je voorwaarden meer dan eens gebruikt. Het herschrijven van code in elk geval kan de kans op fouten vergroten en je code rommelig maken. Laravel lost dit probleem op door dergelijke voorwaarden te verpakken in herbruikbare declarations die scopes worden genoemd.

Query scopes zijn methoden om database-logica aan een model toe te voegen en query logica te hergebruiken.

Hieronder staat een voorbeeld van een query scope. Stel dat je een softwareontwikkelingsplatform voor je team wilt maken dat voltooide en lopende functies bijhoudt. Je kunt deze voorwaarde gebruiken om alleen de lopende functies op te halen:

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

Je hebt deze voorwaarde misschien nodig op andere applicatiepagina’s, zoals de statistiekenpagina. Query scopes zorgen ervoor dat een pagina de bovenstaande conditie kan hergebruiken, waardoor je query eenvoudiger en je code schoner wordt.

Hier zie je hoe je een query scope kunt gebruiken voor dit scenario:

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

Gebruik vervolgens de onderstaande code om die scope uit te voeren:

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

Er zijn twee soorten scopes: globale en lokale.

Globale scopes

Met globale scopes kun je beperkingen toevoegen aan alle query’s binnen een model. Je kunt bijvoorbeeld een voorwaarde toevoegen om functies te filteren op basis van de naam van de team leader in alle query’s binnen je model.

Lokale scopes

Lokale scopes maken het mogelijk om veelvoorkomende constraints te definiëren voor herbruikbaarheid. Je kunt bijvoorbeeld willen dat de applicatie de functies retourneert die bugs hebben. Je code zou een lokale scope als deze kunnen gebruiken:

namespace AppModels;
use IlluminateDatabaseEloquentModel;

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

De bovenstaande code retourneert alle functies die niet-opgeloste bugs hebben.

2. Eloquent relaties

Met relaties in Eloquent kun je verschillende tabellen gemakkelijk aan elkaar relateren. Een product op een e-commerce website kan bijvoorbeeld voorraad, prijs, weergaven en beoordelingen bevatten. Met Eloquent kun je deze relaties eenvoudig beheren, zelfs als hun records in verschillende tabellen staan.

Je kunt relaties definiëren als methoden op model classes, net zoals je dat zou doen met een Eloquent model. Enkele veelgebruikte Eloquent relaties zijn one-to-one, inverse en polymorphic.

One-to-one

Hier is een voorbeeld van een eenvoudige one-to-one relatie die een productmodel koppelt aan een inventaris.

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

In de bovenstaande code callt de methode Inventory() de methode hasOne() op het productmodel. Hiermee wordt gecontroleerd of het product momenteel beschikbaar is.

Inverse

Met Eloquent kun je ook een inverse relatie maken. Bijvoorbeeld als je producten wilt ophalen op basis van het aantal weergaven. Inverse relaties kunnen je de producten geven die de meeste interesse wekken bij de bezoekers van een website. Je kunt de methode belongsTo() gebruiken, die het omgekeerde is van hasOne(). De code hieronder illustreert dit.

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

In de bovenstaande code koppelt Eloquent de product_id aan het aantal doorgegeven weergaven. De product_id kan dan helpen bij het ophalen van andere parameters, zoals prijs en voorraad.

Polymorphic

In applicatieontwikkeling zijn relaties niet altijd eenvoudig. Soms heb je een model dat tot meer dan één modeltype behoort. Product- en voorraadmodellen kunnen bijvoorbeeld beide polymorphic relaties hebben met een afbeeldingsmodel.

Met polymorphic relaties zou je dezelfde lijst met afbeeldingen kunnen gebruiken voor zowel de inventaris als de producten. Hieronder zie je een codefragment dat een polymorphic relatie implementeert.

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');
    }
}

De bovenstaande code gebruikt de methode morphTo() om de parent van het polymorphic model op te halen.

Dit is slechts het topje van de ijsberg over dit onderwerp. Zie voor meer onze gids voor gevorderden over Laravel Eloquent relaties.

3. Eloquent mutators en accessors

Met mutators en accessors kun je gegevens wijzigen terwijl je ze opslaat en ophaalt. Mutators wijzigen gegevens voordat ze worden opgeslagen, terwijl accessors gegevens wijzigen terwijl ze worden opgehaald.

Als je namen in kleine letters wilt opslaan in je database, kun je een mutator maken om die transformatie uit te voeren. Als je de voor- en achternaam van een gebruiker als één naam wilt weergeven op je app pagina’s, kun je een accessor maken om dat te bereiken.

Hieronder zie je een voorbeeld van een mutator die namen een hoofdletter geeft voordat je ze opslaat.

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);
    }
}

Hieronder zie je een voorbeeld van een accessor die de voor- en achternaam van de gebruiker combineert.

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

4. Eloquent collections

Collections in Eloquent behandelen methoden die meerdere modelresultaten teruggeven. Deze klasse is te vinden in IlluminateDatabaseEloquentCollection.

Net als met arrays is het mogelijk om door collections te itereren. Hieronder staat een eenvoudige iteratie.

use AppModelsProduct;

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

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

Collections zijn krachtiger dan matrices omdat je er complexere bewerkingen op kunt uitvoeren. Je kunt bijvoorbeeld de lijst met alle beschikbare producten weergeven en alle producten overslaan die niet “active” zijn

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

Hieronder staan enkele methoden die de klasse Collections biedt.

Contains

De methode contains() controleert of de code een gespecificeerde modus bevat, zoals te zien is in de onderstaande code:

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

All

De methode all() retourneert de modellen in de collections, zoals hieronder getoond:

$collection = Product::all();

Veel andere methoden worden ondersteund door de klasse collections.

5. Eloquent modellen verwijderen

In Eloquent maak je modellen om te helpen bij het bouwen van queries. Soms moet je echter modellen verwijderen om een applicatie efficiënter te maken. Om dit te doen, roep je delete aan op de instantie van het model.

use AppModelsStock;

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

De bovenstaande code verwijdert het model Stock uit een applicatie. Dit is een permanente verwijdering die niet ongedaan kan worden gemaakt.

Soft delete

Een andere functie die Eloquent bevat is de mogelijkheid tot een soft delete. Als je een model soft delete, verwijder je het niet uit de database.

Je markeert het met deleted_at om de tijd en datum van de soft delete aan te geven. Dit is belangrijk als je een deel van de databaserecords wilt uitsluiten, zoals incomplete records, zonder ze permanent te verwijderen. Het helpt bij het opschonen van de query’s van Eloquent zonder extra voorwaarden toe te voegen.

Je schakelt soft delete in door de property softDeletes toe te voegen aan een model en een kolom deleted_at toe te voegen aan de gerelateerde databasetabel.

Soft delete toevoegen aan een model

Je schakelt soft delete van modellen in door de property IlluminateDatabaseEloquentSoftDeletes toe te voegen, zoals hieronder getoond.

namespace AppModels;
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentSoftDeletes;

class Flight extends Model
{
   use SoftDeletes;
}

Een delete_at kolom toevoegen

Voordat je soft delete kunt gaan gebruiken, moet je database een delete_at kolom hebben. Je voegt deze kolom toe met behulp van een Laravel Schema builder helper methode, zoals hieronder getoond:

use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;

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

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

Hiermee voeg je een delete_at kolom toe die wordt bijgewerkt met de datum en tijd, in het geval van een succesvolle soft delete actie.

Soft-deleted modellen opnemen

Als je wilt dat de resultaten van een query ook soft-deleted modellen bevatten, voeg je de methode withTrashed() toe aan de query. Hieronder zie je een voorbeeld:

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

De bovenstaande query zal ook modellen met het deleted_at attribuut bevatten.

Alleen soft-deleted modellen ophalen

Met Eloquent kun je ook alleen soft-deleted modellen ophalen. Je kunt dit doen door bijvoorbeeld de methode onlyTrashed() aan te roepen:

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

Soft-deleted modellen herstellen

Je kunt ook soft-deleted modellen herstellen door de methode restore() te callen.

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

Hiermee wordt het veld delete_at van een soft-deleted model gewijzigd in null. Als het model niet zacht verwijderd is, blijft het veld ongewijzigd.

6. Elegant factories

Model factories in Laravel creëren dummy gegevens die je kunt gebruiken om je applicatie te testen of om je database te vullen. Om dit te implementeren, maak je een model in een factory klasse, zoals in het onderstaande voorbeeld. Het codefragment maakt een model factory die dummy leveranciers van een product en zijn prijzen kan genereren.

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),
        ];
    }
}

De methode definition() in het bovenstaande voorbeeld retourneert een set attribuutwaarden die Laravel gebruikt bij het bouwen van het model. De dummy helper helpt de fabriek om toegang te krijgen tot PHP’s bibliotheek, Faker.

Samenvatting

Eloquent maakt het ontwikkelen van applicaties in Laravel eenvoudiger. Het is even effectief bij het bouwen van eenvoudige of complexe queries, dankzij zaken als relaties. De eenvoud van het genereren van functionele dummy data met behulp van factories maakt het perfect voor developers die robuuste tests willen maken voor hun applicaties. Bovendien helpen Eloquent scopes om complexe queries te vereenvoudigen op een manier die de code netjes houdt.

Hoewel dit artikel slechts zes van de belangrijkste functies heeft besproken, heeft Eloquent nog andere krachtige functionaliteiten. Het gebruik van deelbare en herbruikbare modellen heeft van Eloquent een populaire functie gemaakt onder developers, en de eenvoud van Eloquent query’s maakt Laravel een developersvriendelijk framework – zelfs voor beginners.

Wat je ervaringsniveau ook is, Kinsta’s Web Applicatie Hosting platform ondersteunt developers zoals jij. Onze Laravel Quickstart template laat zien hoe eenvoudig het is om je applicatie aan de slag te krijgen op onze servers binnen het Premium Tier netwerk van 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.