prymribb's avatar

Eager loading all relationships

Is there any easy way to eager load all relationships without having to specify them all in the $with property?

0 likes
4 replies
phildawson's avatar

No as it's not really going to be a common thing, as it'll be wasting queries rather than saving them.

It would be fairly easy though using reflection to test all the methods for a return instance of Relation and set the $with automatically.

PavanKataria's avatar
Level 3

@prymribb Hey, well I wondered the same thing since every single query I was making on my Orders model went hand in hand with a with->(OrderLines::class) at the beginning. So it made sense to want to have something which automatically eager loaded my OrderLines dataset. Another use case in my app, I have another model called Agent which also requires the eager loading of three other models related to it for everything to make sense in the iOS client.

I did some research last week and Taylor Otwell had documented in his Model class a variable which allowed one to set their eager loaded relationships in their own model to automatically enable the loading of relationships without having to specify the with method.

Here's the documentation on that: Model.php

/**
     * The relations to eager load on every query.
     *
     * @var array
     */
    protected $with = [];

All Eloquent models inherit from this class you'll notice the line: class YourModelName extends Model this means you can use the with variable yourself by specifying an array. Here's an example:

    // order
    protected $with = array('orderlines');
    // agent
    protected $with = array('state', 'direction', 'areas');

It's important to remember to only eager load relationships that have to be loaded each and every time, otherwise you will be wasting time on queries especially if you're not going to use them.

In my case it's required. That's how you achieve automatic eager loading.

I hope this will help you and future members visiting this post. If it helped don't forget to mark the answer.

Pavan

8 likes
screenagerbe's avatar

And how would you check prior to PHP 7 that what you return is a relation, without having to execute methods that you perhaps don't want to execute, beginning with all public methods that start with a verb ?

Even if all public methods of your object would return Eloquent relations, they might perform some other things prior to returning the relation. You might not like that.

In my case, I'm trying to build a powerful clone method for my Eloquent objects, that also copies the relations and thereby reallocates or creates new instances of the related objects if necessary. This requires however that I know which relations are there, and such a thing indeed doesn't seem possible with Eloquent. Correct me if I'm wrong.

The only safe solution in my opinion is to rely on PHP interfaces for each Eloquent object you create, and to list up its methods defining Eloquent relations.

aledmb's avatar

great answer Pavan! thanks for taking the time to write it up so nicely! ;)

Please or to participate in this conversation.