0
votes

I have three levels of Category assigned to add product Primary, Secondary, and Final categories. While adding product the user can save the final category id in the category_id field. Now I want to access the product of final categories related to the Primary Category.

Let's suppose I have Electronic Primary category and under that, I have secondary categories like Mobiles, Camera, Desktop and again inside the Secondary categories I have Final category like Samsung, Galaxy inside Mobile, Canon, DSLR inside the camera and so on. Now I want to be able to fetch all the products inside Primary Category.

I have the following code for eager loading:

$electronic_accessories = "Electronic Device";
  
$electronic_accessories_product = Product::whereHas('productCategory', function($query) 
          use($electronic_accessories) {
              $query->whereHas('secondaryCategory', function($query) 
              use($electronic_accessories)  { 
                  $query->whereHas('primaryCategory', function($query) 
                  use($electronic_accessories){
                      $query->where('name', $electronic_accessories);
                  });
              });
        })
        ->with([
          'productCategory' => function($query) use($electronic_accessories) {
              $query->whereHas('secondaryCategory', function($query) use($electronic_accessories)
                { 
                  $query->whereHas('primaryCategory', function($query) 
                    use($electronic_accessories){
                        $query->where('name', $electronic_accessories);
                    });
                });
          },
          'productCategory.secondaryCategory'=> function($query) use($electronic_accessories)
          {
                  $query->whereHas('primaryCategory', function($query) 
                    use($electronic_accessories){
                        $query->where('name', $electronic_accessories);
                    });
          },
          'productCategory.secondaryCategory.primaryCategory' =>                   
            function($query) use($electronic_accessories) {
                  $query->where('name', $electronic_accessories);
          }])->take(2)->get();

This code is working perfectly but I don't want to repeat this code on every time I want to get products from Primary categories. I want to use this as a function. I tried making function with getPrimaryProduct() in Product model but it says

Call to a member function getPrimaryProduct() on null

1

1 Answers

0
votes

You have to use a scope :

public function scopePrimary($query){
   return $query->whereHas('productCategory', function($query) 
          use($electronic_accessories) {
              $query->whereHas('secondaryCategory', function($query) 
              use($electronic_accessories)  { 
                  $query->whereHas('primaryCategory', function($query) 
                  use($electronic_accessories){
                      $query->where('name', $electronic_accessories);
                  });
              });
        })
        ->with([
          'productCategory' => function($query) use($electronic_accessories) {
              $query->whereHas('secondaryCategory', function($query) use($electronic_accessories)
                { 
                  $query->whereHas('primaryCategory', function($query) 
                    use($electronic_accessories){
                        $query->where('name', $electronic_accessories);
                    });
                });
          },
          'productCategory.secondaryCategory'=> function($query) use($electronic_accessories)
          {
                  $query->whereHas('primaryCategory', function($query) 
                    use($electronic_accessories){
                        $query->where('name', $electronic_accessories);
                    });
          },
          'productCategory.secondaryCategory.primaryCategory' =>                   
            function($query) use($electronic_accessories) {
                  $query->where('name', $electronic_accessories);
          }]);
}

then use it :

Product::primary()->get();