Laravel:对嵌套关系中的属性求和

标签 laravel laravel-5 eloquent

我想对一个嵌套集合求和。

我有下表:

  • field
  • 优惠
  • 订单

一个 field 可以有多个报价,一个报价可以有多个订单

示例数据可能是:

field

id        |  name
==========================
5         |  Pizza 4 Less
10        |  Poundland

优惠

id | venue_id | name
==================================
17 | 5        | Buy 1 get one free 
24 | 5        | 30% off pizza
32 | 10       | 50% off
50 | 10       | 20% off

订单

id | offer_id | bill | paid
===========================
85 | 17       | 15   | true
86 | 17       | 20   | true
87 | 17       | 90   | true
88 | 24       | 14   | true
89 | 32       | 15   | true
90 | 32       | 65   | true
91 | 50       | 24   | true
92 | 50       | 1000 | false

我想使用 Laravel Elqouent 模型来获取每个 field 支付的总金额。所以对于上面的数据我想得到以下结果:

id | name          | total_paid
===============================
5  | Pizza 4 Less  | 139
10 | Poundland     | 104

请注意,总数不包括未付款的订单(即订单 92)

我目前的做法如下:

$venues = Venue::with(['offers.orders' => function ($query) {
        $query->where('paid', '=', true);
    }])
    ->get();

$totals = [];
foreach ($venues as $venue) {
    $totalPaid = 0;
    foreach ($venue->offers as $offer) {
        $totalPaid += $offer->orders->sum('bill');
    }
    $totals[$venue->name] = $totalPaid;
}

正如你所看到的,上面的代码效率低下而且很长。

有更好的方法吗?

最佳答案

干净的版本,但效率不高

// In your Venue Model
public function getTotalPaidAttribute()
{
    return $this->offers->sum('TotalPaid');
}

// In your Offer Model
protected $appends = ['totalPaid'];

public function getTotalPaidAttribute()
{
    return $this->orders->sum('paid');
}

// use it : 
foreach($venues as $venue){
     //do what you want with it
     $venue->totalPaid;
}

(已编辑)

正如评论中所说,这种方法可能更干净,但效率不高:

有效的方法:

// In your Venue Model
public function orders(){
    return $this->hasManyThrough(Order::class, Offer::class)
        ->selectRaw('sum(paid) as aggregate, venue_id')
        ->groupBy('venue_id');
}

public function totalPaid(){
    if ( ! array_key_exists('orders', $this->relations)) $this->load('orders');
    $relation = $this->getRelation('orders');

     return ($relation) ? $relation->aggregate : 0;
}

public function getTotalPaidAttribute()
{
    return $this->totalPaid();
}

也许我弄乱了你的 key ,你可能必须使用关系的完整声明:

return $this->hasManyThrough(
        Order::class, Offer::class
        'venue_id', 'offer_id', 'id'
    );

但是我刚刚完成了我的项目,它就像一个魅力

关于Laravel:对嵌套关系中的属性求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44330130/

相关文章:

javascript - 从 javascript 获取输入值时无法将值传递给 Controller

mysql - Laravel 限制,但如果在顶部则返回超过限制

php - 从 Eloquent 辅助表中选择所有字段

css - 来自存储的 Laravel 背景图片

php - Laravel 5 使用 Ajax 发送密码重置链接

Laravel afterFind 回调事件

php - 如何在 Laravel Blade View 中突出显示字符串中的字符串

php - 我可以在 Laravel 的路由组中使用域和端口吗?

php - 如何过滤数据库查询结果以不显示任何重复的外键?拉维尔

laravel - 将应用程序从宅基地移至Docker