Im building a simple buy and sell application with Laravel 5.1. Each Buy Model has many BuyDetail which stores bought item quantity and buy_price. I have implement the relations
I realise an answer’s already been accepted, but just thought I’d add my own detailing another approach.
Personally, I like to put “aggregate” methods like these on custom collection classes. So if I have a Buy
model that can have many BuyDetail
models, then I would put a getTotal()
method on my BuyDetailCollection
method like this:
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
class BuyDetailCollection extends EloquentCollection
{
public function getTotal()
{
return $this->items->sum(function ($detail) {
return $detail->price * $detail->quantity;
});
}
}
I can then add this to the BuyDetail
model:
class BuyDetail extends Model
{
public function newCollection(array $models = [])
{
return new BuyDetailCollection($models);
}
}
And use my getTotal()
method where ever I need to now:
$buy = Buy::with('buyDetails')->find($id);
$total = $buy->buyDetails->getTotal();
This can be done in (at least) 2 ways.
Using pure Eloquent model logic:
class Buy extends Model
{
public function getTotalPrice() {
return $this->buyDetails->sum(function($buyDetail) {
return $buyDetail->quantity * $buyDetail->price;
});
}
}
The only issue here is that it needs to fetch all buy details from the database but this is something you need to fetch anyway to display details in the view.
If you wanted to avoid fetching the relation from the database you could build the query manually:
class Buy extends Model
{
public function getTotalPrice() {
return $this->buyDetails()->sum(DB::raw('quantity * price'));
}
}