0

I have a complex relationship like a ManyToMany relationship between Category and Products and a Product can have many Inventory listings from different Shops(user). A Shop can have multiple listing of the same Product as a variant(color/size).

Everything is fine till now!

The issue begins when showing the listing to the visitors. I want to show all listings under a category but don't want to show multiple listings of the same product from the same shop. Instead, want to pick the lowest sale_price listing from the shop.

I have three models and relations are like:

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


     class Product extends Model
     {

        public function categories()
        {
            return $this->belongsToMany(Category::class);
        }

        public function inventories()
        {
            return $this->hasMany(Inventory::class);
        }
    } 


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

    }

Tables:

    //Categories
    Schema::create('categories', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name')->unique();
    });


    //Products
    Schema::create('products', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name')->unique();
    });

    //Pivot table
    Schema::create('category_product', function (Blueprint $table) {
        $table->integer('category_id');
        $table->integer('product_id');
    });


    //Inventories
    Schema::create('inventories', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('shop_id');
        $table->integer('product_id');
        $table->string('sku', 200);
        $table->string('title');
        $table->decimal('sale_price', 10, 2);
    });

As Laravel doesn't provide any manyToManyThough() relationship. I have added a listings method in the Category model. This method returns all listings:

public function listings()
{
    $product_ids = $this->products()->pluck('products.id')->all();

    return Inventory::whereIn('product_id', $product_ids)->paginate(20);
}

Then I tried this:

public function listings()
{
    $product_ids = $this->products()->pluck('products.id')->all();

    return Inventory::whereIn('product_id', $product_ids)->groupBy('shop_id','product_id')->paginate(20);
}

These methods produce MySQL GroupBy Error. Yes, I can filter the result after taking all result but that'll affect the pagination. How to get the sorted results and also keep the pagination ability. Thanks and day by day I got more indebted to the community. :)

Munna Khan
  • 1,902
  • 1
  • 18
  • 24

1 Answers1

1

You can create a direct relationship by "skipping" the products table:

public function listings() {
    return $this->belongsToMany(
        Inventory::class,
        'category_product',
        null,
        'product_id',
        null,
        'product_id'
    );
}
Jonas Staudenmeir
  • 24,815
  • 6
  • 63
  • 109