Laravel Eloquent: Best Way to Calculate Total Price

蹲街弑〆低调 提交于 2019-12-21 07:11:33

问题


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 relationship between table on the Model.

class Buy extends Model
{
  #Eloquent relationships

  public function supplier()
  {
    return $this->belongsTo('App\Supplier');
  }

  public function buyDetails()
  {
    return $this->hasMany('App\BuyDetail');
  }
}

I'd like to calculate the total price for each Buy. What is the best way to calculate the total price using Eloquent ORM?

for now i just implement it like this:

@foreach($buys as $key => $value)
    <?php
        $total = 0;
    ?>
    @foreach($value->buyDetails as $k => $bD)
        <?php
            $total += ($bD['buy_price']*$bD['qty']);
    ?>
    @endforeach

   <tr>
    <td>{{$value->ref_number}}</td>
    <td>{{$value->suplier->name}}</td>
    <td>{{$value->created_at}}</td>
    <td>{{$value->buyDetails->count()}}</td>
    <td>{{$total}}</td>
    <td>
        <a href="" class="btn btn-default btn-sm" title="show">Detail</a>
        <a href="" class="btn btn-primary btn-sm" title="edit">Edit</a>
        <a href="" class="btn btn-danger btn-sm" title="delete">Delete</a>
    </td>
  </tr>
@endforeach

回答1:


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'));
  }
}



回答2:


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();


来源:https://stackoverflow.com/questions/31421666/laravel-eloquent-best-way-to-calculate-total-price

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!