0

Let's say I have these modules:

  • Coupon
  • Order (.., coupon_id)
  • Item (..., order_id, price)

And there are those relations:

  • Coupon Has Many Order.
  • Order Has Many Item.

So far so good.

Now I want to sum the price of the items that belongs to the orders that belongs to the coupon. So I thought about doing something like this:

Coupon::orders->items->sum('price'); 

Well, it won't work because orders() method returns a Collection of the relation:

/** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function orders() { return $this->hasMany(Order::class); } 

I'm getting an error that says item property is protected. I found out that it doesn't related to my Item module, it's just because Collection has protected $items = [];.

So, after I cleared out some facts, my question/problem is, How can I sum the items->price of the orders that belong to Coupon?


Of course I can achieve my goal by doing a foreach loop like this:

$price = 0; foreach (Coupon:orders as $order) $price += $order->items->sum('price'); return $price; 

But I'm looking for a cleaner solution. Anyone?

1 Answer 1

10

A few ways to achieve that:

$coupon_id; // the one you're looking for Item::whereHas('order', function ($q) use ($coupon_id) { $q->where('coupon_id', $coupon_id); })->sum('items.price'); // OR // Coupon model public function items() { return $this->hasManyThrough(Item::class, Order::class); } Coupon::find($coupon_id)->items()->sum('price') // aggregate query Coupon::find($coupon_id)->items->sum('price') // sum on collection // OR Coupon::with('orders.items')->find($coupon_id)->orders->pluck('items')->collapse()->sum('price'); 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I've used the third option.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.