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
$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.
@MohamedTammam thank you very much. I'm going to try the database view that Tray recommended
@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.
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.