PeregrineStudios's avatar

->with() query not working; can't figure out why

I'm struggling a bit, here: I can't figure out why this Eloquent query isn't automatically including my images relationship.

Here's the relationship:

class ImagesetCrop extends Model {
    ...
    
    public function images(): BelongsToMany
    {
        return $this->belongsToMany(File::class)->withPivot('height', 'width', 'left', 'top');
    }
}

And here's me dumping out the SQL to figure out what's wrong:

dd($this->resource->crops()
    ->with('images')
    ->orderBy(DB::raw('CONCAT(width, "x", height)'))
    ->toRawSql());

The SQL I get back from that dump contains nothing, at all, about including the images in the query as well:

select * from "imageset_crops" where "imageset_crops"."imageset_id" = 'fc7c4512-1c59-4701-a55a-01fe2e924b05' and "imageset_crops"."imageset_id" is not null order by CONCAT(width, "x", height) asc

Honestly, I just don't know why it isn't working. I must have written hundreds of Eloquent queries like this before. Am I just stupidly overlooking something?

EDIT: Annoyingly, it actually works fine in the browser. It's only in test-land that the eager loading doesn't seem to be working at all.

2ND EDIT: After loads of of debugging down to the simplest version of the problem, still no answers.

$imagesetCrop = ImagesetCrop::query()->with('images')->first();
dd($imagesetCrop->images);

The above code dumps out an empty Collection. However:

dd($imagesetCrop->images()->get());

That code brings back the expected Collection of File models. So it's specifically and only the eager loading that is failing, for some reason.

0 likes
11 replies
jlrdw's avatar

How are you storing the images? If storing, the query returns names, you need asset helper to display them.

<img src="{{ asset('upload/imgdogs') . '/' . $row->dogpic }}

Of course provide an alt.

PeregrineStudios's avatar

@jlrdw This has nothing at all to do with front-end assets. These are rows in a database. This is about Eloquent relationships.

migsAV's avatar

@peregrinestudios the relationship for images is on your ImagesetCrop Model but you are getting data from $this->resource .

What Model is $this->resource ?

PeregrineStudios's avatar

@migsAV That code is from a JsonResource class. $this->resource is an Imageset, which has a ->crops() relationship to many ImagesetCrops.

Snapey's avatar

The SQL I get back from that dump contains nothing, at all, about including the images in the query as well:

Thats not how relationships work. Eloquent will create one query for the initial model, and more, separate queries the relations.

Install a product like Laravel Debugbar to inspect all queries on the request.

PeregrineStudios's avatar

@Snapey I thought surely this was a mistake, so I did more reading on eager loading. You're right; even when eager loading, Eloquent still makes two queries, one for the initial model and another one for the relationships. That still doesn't explain why it doesn't work at all, but it does explain what I'm seeing in my dd().

PeregrineStudios's avatar
Level 1

This was a really obtuse one for me to find. After dding my way through the Laravel QueryBuilder class, I was finally able to determine that the problem was that it was converting my string UUIDs to integers when trying to run the join statement between my related models. That finally gave me something concrete I could look up on Google, which led me here: https://laracasts.com/discuss/channels/eloquent/eager-loading-not-working-with-particular-uuid

Long story short: adding protected $keyType = 'string'; to both models finally solved the issue.

Please or to participate in this conversation.