Skip to content
Advertisement

Laravel 5.3 creating multi dimention array from DB results

Reuqirment

My DB has a table named categories and also a table named products where products table has a row named category_id which make the relationship with categories table. So I wants to show random 7 categories from my categories table and also I needs to show 6 products from each category too.

Framework

Laravel 5.3

What I have done

  • To fetch 8 random categories

    This code work as I wants so no issue with this code segment

     $masterCategoryList = Category::where('parent_id', 0)
                                      ->where('id', '!=',0)
                                      ->inRandomOrder()
                                      ->take(8)
                                      ->get();
    
  • Fetch 6 random products for each selected random Master Category List id $masterCategoryList So what I have done is

    $productsMatcheToMasterCategory = []; 
    
             for($a = 0; $a<8; $a++){
    
       $productsMatcheToMasterCategory =
                               Product::where('category_id',$masterCategoryList[$a]['id'])    
                               ->inRandomOrder()
                               ->take(6)
                               ->get();    
     }
    

But this only output 6 products which related one category when I use dd($productsMatcheToMasterCategory)after the loop.Like below

 Category 01

       - Product 01

       - Product 02

My expected out put is something like below

Category 01
           - Product 01
           - Product 02
Category 02
           - Product 01
           - Product 02

Could anyone please tell me why does this happen.

Thanks

Advertisement

Answer

In the way you are doing it, you are overriding the value you previously assigned to the variable. To avoid that, add an empty pair of brackets to the variable to indicate that you assign each result of each query in the loop to a new element in the array.

$masterCategoryList = Category::where('parent_id', 0)
                                ->where('id', '!=',0)
                                ->inRandomOrder()
                                ->take(8)
                                ->get();

$productsMatcheToMasterCategory = []; 

for($a = 0; $a < 8; $a ++) {
    // here note the $productsMatcheToMasterCategory [] = ...
    $productsMatcheToMasterCategory [] = Product::where('category_id',$masterCategoryList[$a]['id'])    
                                                ->inRandomOrder()
                                                ->take(6)
                                                ->get();    
}

but in that way you have 9 queries, 1 to get the eight categories and 8 to get the products for each category.

Another approach I can think of is by defining the relationships in the models:

class Category extends Model
{
    public function products()
    {
        return $this->hasMany(Product::class, 'category_id');
    }
}



class Product extends Model
{
    public function category()
    {
        return $this->belongsTo(Category::class);
    }
}

and getting the related products by the method with() constraining the eager loads, wich results in just one query:

$collection = Category::where('parent_id', 0)
            ->where('id', '!=',0)
            ->inRandomOrder()
            ->take(8)
            ->with([
                'products' => function($query) {
                    $query->inRandomOrder()
                          ->take(6);
                },
            ])
            ->get();
$array = $collection->toArray();
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement