Emil Österlund

Automatisk eager loading i Laravel

Ett litet inspel om eager loading i Laravel.

Först och främst - installera barryvdh/laravel-debugbar. Den är GRYM på att visualisera saker man annars inte tyckte man hade koll på. Bland annat låter den dig se hur många sql-queries din sidladdning gör, hur många views som laddas och vad som tar tid. Dessutom kan man logga själv till dess debug-fönster. Den är grym.

Eager loading då. Jo, http://laravel.com/docs/5.1/eloquent-relationships#eager-loading förklarar det ungefär så här. Tänk att du har en modell Book som ser ut så här:

Tänk att du har en modell som ser ut så här:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * Get the author that wrote the book.
     */
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}

Om du då vill hämta alla böckers författares namn så blir koden så här:


$books = App\Book::all();

foreach ($books as $book) {
    echo $book->author->name;
}

Det fungerar. MEN, den kommer då att först göra ett uppslag för att få fram alla böcker, och sen slå i Authors tabellen en gång för varje bok. och det blir fort väldigt många queries. Är det 25 böcker så blir det 26 queries.

Introducing eager loading

Om vi istället skriver vår kod när vi laddar alla böcker så här:


$books = App\Book::with('author')->get();

foreach ($books as $book) {
    echo $book->author->name;
}

Nu kör den bara två queries istället, trots samma mängd böcker.

Allt detta står i den förträffliga dokumentationen. Men jag har ett eget guldkorn som jag tycker är för bra för att inte nämnas, och vad jag vet INTE nämns i dokumentationen.

Automatisk eager loading för en modell

Det går att automatiskt ladda en relation med eager loading, så att om man t.ex har modellen för bok, så är författaren alltid laddad. det är så enkelt att man i modellen för bok bara lägger till den här lilla kodsnutten:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * Automaticly eager load the author
     */
    protected $with = ['author'];

    /**
     * Get the author that wrote the book.
     */
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}

Genom att lägga till den lilla variabeln i modellen så kommer modellen Book nu alltid att innehålla sin relation till Author. Voila!