NicolasV's avatar

How to configure automatic eager loading in models

Let's take a basic model with a relation

class Book extends Model
{
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}

Eloquent allows eager loading authors when selecting the books:

$books = App\Book::with('author')->get();
foreach ($books as $book) {
    echo $book->author->name;
}

Is there a way to indicate in the Book that all books should always be loaded with eager loading so we don't have to indicate it in the query? As example something like this:

class Book extends Model
{
    public function author()
    {
        return $this->belongsTo('App\Author');
    }

    protected $eagerload = ["author"];
}

This is to avoid having to specify it in each query if we know that we will always need the author when having the book. This feature exists in most other ORMs (Hibernate has it as example) and this becomes especially important if we use accessors like this:

class Book extends Model
{
    public function author()
    {
        return $this->belongsTo('App\Author');
    }

    public function getAuthorNameAttribute()
    {
        return $this->author->name;
    }
    protected $appends = ['author_name'];
}

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

foreach ($books as $book) {
    echo $book->author_name; // here we don't even know we are using the author relation
}
0 likes
2 replies
pmall's avatar
pmall
Best Answer
Level 56

Is there a way to indicate in the Book that all books should always be loaded with eager loading

Add a with attribute in the model. It contains an array or the relationships which should be automatically eager loaded.

class Book extends Model
{
    public $with = ['author'];
}
12 likes
shez1983's avatar

didn't know that.. Laravel rules...

also I thought i could use that.. but i cant.. how could I do the same thing with scopes set up? perhaps not the best idea but just intrigued? so i have a scopeLive() which only returns live users.. instead of doing users::Live()->get().. i can just do users::all() or something...

1 like

Please or to participate in this conversation.