web-dev-qa-db-ja.com

Laravel雄弁:合計価格を計算する最良の方法

Laravel 5.1を使用して簡単な売買アプリケーションを作成しています。5.1。各購入モデルには、購入したアイテムの数量とbuy_priceを格納する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
15
Wendy Adi

これは(少なくとも)2つの方法で実行できます。

純粋な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'));
  }
}
12
jedrzej.kurylo

回答はすでに受け入れられていることに気づきましたが、別のアプローチの詳細を自分で追加したいと思いました。

個人的には、このような「集約」メソッドをカスタムコレクションクラスに配置するのが好きです。したがって、多くのBuyモデルを含むことができるBuyDetailモデルがある場合、BuyDetailCollectionメソッドにgetTotal()メソッドを次のように配置します。

_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();
_
7
Martin Bean