mercredi 13 septembre 2017

Eager loading when calling a relation

i have these tables in my db and they are related

category
products
product_images
product_categories 

in Category model i have (pleas ignore syntax errors)

function ProductCategoryLatest()
{
    return $this->hasMany('App\ProductCategory')->limit(6);
}

in my ProductCategory model i have

   function Product(){
       return $this->belongsTo('App\Product')->where('hidden' , 0 );
   }

in Product model i have

   function Image(){
       return $this->hasMany('App\Image');
   }

i want to show last 6 product of each category in my index so i read and send categories from controller to my view

$categories = Category::all();
return view('index' , compact('category'));

in the view i have something like

@foreach($categories as $category)

       products :

     @foreach($category->ProductCategoryLatest as $product_category )

             

             @foreach($product_category->Product->Image as $image  )
                 <img src="">
             @endforeach


     @endforeach

@endforeach

as you can imagine there are lots of queries that can be avoided by eager loading but the thing is that limit 6 is ruining it

like if i write my query like

$categories = Category::with('ProductCategoryLatest' , 'ProductCategoryLatest.Product' , 'ProductCategoryLatest.Product.Image')->get();

and i have 5 category in my db the query would be something like

select * from product_categories  where category_id  in (1,2,3,4,5) LIMIT 6 

so if category with id 1 has like 10 rows in product_categories all the 6 returned rows would belong to category 1 and the rest would come back empty even tough they have associated rows in db but that limit 6 would cuz them to show up without any row in product_categories

so basically i need to eager load in the view on relation something like

@foreach($categories as $category)


    @foreach($category->ProductCategoryLatest->with('Product' , 'Product.Image' ) as $product_category )

    @endforeach


@endforeach

btw i know i can do some juggling in the controller like

$new_categories = [] ;
foreach ($categories as $category )
{
    $ProductCategoryLatest  = ProductCategoryLatest::where('category_id' , $category->id )->with('Product' , 'Product.Image')->get();
    $category->addAtribut = $ProductCategoryLatest ;
    $new_categories[] = $category ;
}

but i wonder if there is a cleaner solution ?



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire