Laravel Eloquent: лучший способ расчета общей цены
Я создаю простую заявку на покупку и продажу с Laravel 5.1. Каждая модель покупки имеет много BuyDetail, в котором хранится купленное количество товаров и buy_price. Я реализую связь между таблицей на модели.
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
Ответы
Ответ 1
Это может быть сделано (по крайней мере) двумя способами.
Использование чистой логики модели 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'));
}
}
Ответ 2
Я понимаю, что ответы уже приняты, но просто подумал, что Id добавляет мою собственную детальную информацию о другом подходе.
Лично мне нравится ставить "совокупные" методы, подобные этим, в пользовательских классах коллекции. Поэтому, если у меня есть модель 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();