Chris
Chris

Reputation: 2035

Laravel eager loading deep relationships

I've hit a bit of a snag with Laravel and eager loading relationships. I have three models AssetFolder, Asset & DownloadLog

I'm currently querying for a particular asset folder, and in doing so I'm eager loading the assets.

$folder = AssetFolder::where('name', 'Example')
    ->with([
        'assets' => function (HasMany $query) {
            $query->orderBy('name', 'asc');
        }
    ])->first();

This part works great. But for the purposes of this query, I'd also like to eager load each Asset associated DownloadLog records. I've tried solution #1 -

$folder = AssetFolder::where('name', 'Corporate Assets')
    ->with([
        'assets' => function (HasMany $query) {
            $query->orderBy('name', 'asc');
        },
        'assets.downloads'
    ])->first();

I'd now expect my Asset model to contain a relationship called downloads full of DownloadLog objects but unforunately that wasn't the case. The downloads relationship wasn't even referenced. So then I tried solution #2 -

$folder = AssetFolder::where('name', 'Corporate Assets')
    ->with([
        'assets' => function (HasMany $query) {
            $query
                ->with('downloads')
                ->orderBy('name', 'asc');
        }
    ])->first();

This didn't work either - same result as above. Now I would have expected that to work but it didn't. So to test, I went into my AssetFolder model and updated my HasMany relationship method to the following -

public function assets()
{
    return $this
        ->hasMany(Asset::class)
        ->with('downloads');
}

And that works! That's great, but the problem is that 90% of the time, I don't want to pull the download logs along with the assets I'm loading. That's why I thought solution #2 would work because I thought it simply altered the HasMany query.

Am I doing something wrong here?

Chris.

Upvotes: 1

Views: 2296

Answers (1)

user3325126
user3325126

Reputation: 1384

Just create a different relation in the AssetFolder model specifically for that purpose and eagerload with that.

public function assetsWithDownloads()
{
    return $this
        ->hasMany(Asset::class)
        ->with('downloads');
}

Upvotes: 1

Related Questions