aurelianspodarec's avatar

Eager Load Images

Hi there!

So I've created a filter that eager loads data.

Now I'm uploading images and here's the issue I figured out I have:

  • Where there is no filtering applied, no eager loading, the retrieving images works fine, I'm using Spatie so this <img src="{{ asset($image->getFirstMediaUrl('image')) }}" works just fine.
  • On the page that has exactly the same data, but has filtering and eager loading applied, that there won't work now.

From my understanding it has to do with how I'm loading the data, and I need to get the data in a different way,

So I'm not quite sure how I'm supposed to proceed with this.

I got this:

class SitePageImage extends Model implements HasMedia
{

    // TODO: Renamte this to SitePageVariation
    
    use HasFactory;
    use InteractsWithMedia;
    
    public function featuredImage()
    {
        return $this->morphOne(Media::class, 'model')->where('collection_name', '=', 'image');
    }

    public function variation()
    {
        return $this->belongsTo(SiteVariation::class, 'site_variation_id');
    }

    public function registerMediaConversions(Media $media = null): void
    {
        $this
            ->addMediaConversion('preview')
            ->width(100)
            ->height(100);
    }

}

AndI just added the featuredIamge just to get any image for a test now, and I feel like I need to use some poymorphis relationship for this maybe?

But I though spatie methods would also do that automatically, but maybe they are used only on a non filtering/eager loading data, so if I change the way the data loads, I need to then create my own methods to retrieve the data from the media table right?

0 likes
5 replies
jlrdw's avatar

Image name should be in a field in database, it's loaded with data. It's just another field. I.E.,

        @foreach ($dogs as $row)
        <tr>
            @if (empty($row->dogpic))
                <td class="imgtd">&nbsp;</td>
            @else
                <td class="imgtd"><img src="{{ asset('upload/imgdogs') . '/' . $row->dogpic }}" alt="" class="image"></td>
            @endif
                <td class="dname">{{ $row->dogname }}</td>
                <td class="dsex">{{ $row->sex }}</td>
                <td class="dogcomment">{{ $row->comments }}</td>
                 etc
1 like
aurelianspodarec's avatar

@jlrdw So my issue is that my image doesn't load where I use filters, but loads where I don't use them like this:

<img src="{{ asset($image->getFirstMediaUrl('image')) }}"

I was reading this https://spatie.be/docs/laravel-medialibrary/v10/basic-usage/retrieving-media and this https://spatie.be/docs/laravel-medialibrary/v10/converting-images/retrieving-converted-images

So I'm not sure why wouldn't that work in that case

The thing is, the component works on a different page.

However I've noticed my pagination doesn't work where the filter is - so maybe that's the issue I need to solve first.

Yep! Something here is breaking the code it seems


            public function scopeFilter($query, array $filters) {

        $query->when($filters['color'] ?? false, fn($query, $color) =>
            $query->whereHas('site.color', function ($query) use ($color) {
                $query->where('name', $color);
            })->get()
        );

        $query->when($filters['page'] ?? false, fn($query, $page) =>
            $query->whereHas('categoryPage', function ($query) use ($page) {
                $query->where('name', $page);
            })->get()
        );

        $theme = $filters['theme'] ?? 'light';
        $device = $filters['device'] ?? 'desktop';

        $query->with('imageVariations', function($query) use ($theme, $device) {
            $query->join('site_variations', 'site_variation_id', 'site_variations.id')
                        ->where('site_variations.theme', $theme)
                        ->where('site_variations.device', $device);
        })->get();
  
    }

And to be exact, this code here breaks the image:

 $query->with('imageVariations', function($query) use ($theme, $device) {
            $query->join('site_variations', 'site_variation_id', 'site_variations.id')
                        ->where('site_variations.theme', $theme)
                        ->where('site_variations.device', $device);
        })->get();
  

And the code above that breaks the pagination xd

So I have some issues with the filter, I guess that's the main issue.

And I can see why the above would break the pagination, because I'm using a reserved word for pagination here:

 // $query->when($filters['page'] ?? false, fn($query, $page) =>
        //     $query->whereHas('categoryPage', function ($query) use ($page) {
        //         $query->where('name', $page);
        //     })->get()
        // );

filters page.... but that's actually used for pagination, which means I need to change that to be something else and that should fix the filter.

So in that case just need to fix the image breaking form the below xd Yeah, I did that and it works, I just fixed myself the pagination lol totally unrelated to this.

In that case the other piece of code breaks the image for some reason. So I think need new question for that.

iftekhs's avatar

I think you can eager load the data meaning the image field which can be the path of the image or the image file name but I don't think there is anything to eager load the image.

1 like
MohamedTammam's avatar

What's the value of dd($filters['theme']) and dd($filters['device']), are you sure you have a records that match that filters?

aurelianspodarec's avatar

Well, so the default value is set here:

$theme = $filters['theme'] ?? 'light';
        $device = $filters['device'] ?? 'desktop';

I have a variation table, and the filter works. I get the variation by ID based on theme and device.

The filtering works. But what doesn't is the image being loaded. The filter showing the correct filtered post does work though. The correction variation is displayed based on the filter.

Please or to participate in this conversation.