18

我用 Laravel 5.1 构建了一个简单的买卖应用程序。每个 Buy 模型都有许多 BuyDetail,其中存储了购买的商品数量和购买价格。我已经在模型上实现了表之间的关系。

class Buy extends Model
{
  #Eloquent relationships

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

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

我想计算每次购买的总价格。使用 Eloquent ORM 计算总价的最佳方法是什么?

现在我只是这样实现它:

@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
4

2 回答 2

17

这可以通过(至少)两种方式完成。

使用纯 Eloquent 模型逻辑:

class Buy extends Model
{
  public function getTotalPrice() {
    return $this->buyDetails->sum(function($buyDetail) {
      return $buyDetail->quantity * $buyDetail->price;
    });
  }
}

这里唯一的问题是它需要从数据库中获取所有购买详细信息,但无论如何您都需要获取这些信息才能在视图中显示详细信息。

如果您想避免从数据库中获取关系,您可以手动构建查询:

class Buy extends Model
{
  public function getTotalPrice() {
    return $this->buyDetails()->sum(DB::raw('quantity * price'));
  }
}
于 2015-07-15T07:14:14.263 回答
9

我意识到答案已经被接受,但只是想我会添加我自己的详细信息另一种方法。

就个人而言,我喜欢将这些“聚合”方法放在自定义集合类中。因此,如果我有一个Buy可以有多个BuyDetail模型的模型,那么我会getTotal()在我的方法上放置一个方法,BuyDetailCollection如下所示:

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

然后我可以将它添加到BuyDetail模型中:

class BuyDetail extends Model
{
    public function newCollection(array $models = [])
    {
        return new BuyDetailCollection($models);
    }
}

getTotal()并在我现在需要的任何地方使用我的方法:

$buy = Buy::with('buyDetails')->find($id);

$total = $buy->buyDetails->getTotal();
于 2015-07-15T08:41:18.710 回答