简体   繁体   中英

How to eager load Aggregates in Laravel with Eloquent?

in my application I have a long list of Categories. I load them with this:

$categories = Categories::all();

In the Categories there is this function:

public function transactions()
{
    return $this->hasMany(Transactions::class);
}

public function getPreviousActivityAttribute() {
    return $this->transactions()
        ->where('date', '<' Carbon::now()->firstOfMonth())
        ->sum('amount');
}

I render this list of Categories as a table. Each row is calling $category->previousActivity .

This results in n+1 database queries, where n is the number of Categories (and its a lot). Apart from previousActiviy I display other Aggregates aswell (some do SUM others do AVG , etc.).

By the way. There are a lot of transactions. I cannot load them all using Categories::with('transactions')->get() . This would require too much memory.

Is there a way to eager load aggregates? There is a withCount method on the query builder, but it does not really help here.

Thank you for your help.

A clean solution would be to use withCount as follows:

In Categories.php:

public function withPreviousActivity()
    {
        return $this->withCount([
            'transactions as previous_activity' => function ($query) {
                $query->select(DB::raw("SUM(IFNULL(amount,0)) as transactions_count"))->where('date', '<', Carbon::now()->firstOfMonth());
            },
        ]);
    }

Somewhere else:

dump(Categories::withPreviousActivity()->get()->toArray());

Attach a function to the withCount attribute in the model˚s constructor like this to always eager load this count.

public function __construct(array $attributes = array())
{
    parent::__construct($attributes);

    $this->withCount['transactions as total'] = function ($query) {
        $query->select(DB::raw(
            'SUM(IFNULL(amount, 0)) as relationsum'
        ));
    };
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM