Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

SigalZ's avatar
Level 5

Query complex relationships

Hello,

Using Laravel 10 I have a complex database structure and I need help querying it.

I have these tables with relationships:

variant_types:
public function productVariantTypes()
{
    return $this->hasMany(ProductVariantType::class);
}

product_variants:
public function productVariantType()
{
    return $this->belongsTo(ProductVariantType::class);
}

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

 public function variantType()
 {
    return $this->belongsTo(VariantType::class);
 }

 public function productVariants()
  {
    return $this->hasMany(ProductVariant::class);
  }

products:
public function productVariantTypes()
{
    return $this->hasMany(ProductVariantType::class);
}

 public function variants(): HasManyThrough
 {
     return $this->hasManyThrough(ProductVariant::class, ProductVariantType::class);
 }

orders:
public function orderItems()
{
    return $this->hasMany(OrderItem::class);
}

order_items:
 public function order()
 {
    return $this->belongsTo(Order::class);
 }

 public function productVariant()
 {
    return $this->belongsTo(ProductVariant::class);
 }

// On this model I also added this method:
public function getProduct()
{
    return $this->productVariant->productVariantType->product;
}

// Not sure if there's a better way.

Data example:

variant_types:
| id | name     |
| -- | -------- |
| 1  | Bag Size |


products:
| id | name           | product_type |
| -- | -------------- | ------------ |
| 1  | Espresso Blend | Blend        |
| 3  | Brazil         | Bean         |
| 4  | Colombia       | Bean         |

product_variant_types:
| id | product_id | variant_type_id |
| -- | ---------- | --------------- |
| 1  | 1          | 1               |
| 3  | 3          | 1               | 
| 4  | 4          | 1               |

product_variants:
| id | product_variant_type_id | value | price  |
| -- | ----------------------- | ----- | ------ |
| 1  | 1                       | 250g  | 95.00  |
| 2  | 1                       | 1kg   | 320.00 |
| 3  | 3                       | 250g  | 100.00 |
| 4  | 3                       | 1kg   | 365.00 |
| 5  | 4                       | 250g  | 85.00  |
| 6  | 5                       | 1kg   | 300.00 |

orders:
| id   |
| --   |
| 3429 |

order_items:
| id | order_id | product_variant_id |
| -- | -------- | ------------------ |
| 1  | 3429     | 2                  |
| 2  | 3429     | 4                  |
| 3  | 3429     | 6                  |

For each order, I need to display the items grouped by the product type.

So with the example data I will display:

Blends:

Espresso Blend

Beans:

Brazil

Colombia

0 likes
5 replies
MohamedTammam's avatar
$groupedItems = $order->orderItems->groupBy((function($item) {
	return $item->productVariant->ProductVariantType->name;
});
@foreach($groupedItems as $name => items)
	<div>{{ $name }}</div>
	<ul>
		@foreach($items as $item)
		<li>{{ $item->getProduct->name }}</li>
		@endforeach
	</ul>
@endforeach

PS: I'm assuming all data are loaded already. If not, there's might be more performant way using SQL.

SigalZ's avatar
Level 5

@Tray2 oh wow, that sounds awesome. I'm going to try it when I'm back at my pc.

I'll come back here after I try it. Thank you very much.

SigalZ's avatar
Level 5

Just an update, the needs for my code changed, so I don't need a solution here anymore, but I would have used the db view solution.

Please or to participate in this conversation.