rdx / laravel-aggregate-relationships
在 Laravel 中实现 COUNT() 和 SUM() 等关系,无需使用 withCount()
1.8
2024-04-18 18:19 UTC
Requires
- php: ^8.0
README
是什么? - Laravel 已经有关系了
Laravel 可以与其他模型建立关系,但不能与标量(例如数字)建立关系。此包可以 COUNT()
和 SUM()
关系。特别是 COUNT()
非常有用,因为……
为什么? - Laravel 有这个功能!
不。在 Laravel 中,唯一计数关系的方法是使用 withCount()
,但……
- 只能用于 预加载,不能用于 懒加载
- 不能在对象存在后,在集合上调用(如
->load('name')
) - 总是命名为
{name}_count
如何实现?
将特性添加到您的模型/基础模型中
use RelatesToAggregates;
这会公开方法 hasCount(relatedClass, foreignKey)
,hasAggregate(relatedClass, aggregateColumn, foreignKey)
和 hasManyScalar(targetKey, targetTable, foreignKey)
定义关系
class User extends Model { use RelatesToAggregates; // Number of transactions for this user function num_transactions() { return $this->hasCount(Transaction::class, 'user_id'); } // Sum of all positive and negative transactions for this user function current_balance() { return $this->hasAggregate(Transaction::class, 'sum(money_change)', 'user_id'); } // List of payment uuids function payment_refs() { return $this->hasManyScalar('reference_uuid', 'transactions', 'user_id'); } }
然后像正常关系一样预加载它
$users = User::with(['address', 'fav_color', 'num_transactions', 'current_balance', 'payment_refs'])->get();
或者以后,像正常关系一样,与 Laravel 的计数不同
$users = User::all(); $users->load(['address', 'fav_color', 'num_transactions', 'current_balance', 'payment_refs']);
如果不能/不想预加载它,则可以懒加载它,就像正常关系一样
$user = User::find(123); echo "Balance: {$user->current_balance} ({$user->num_transactions} transactions): " . implode(', ', $user->payment_refs);
总结
- 预加载和懒加载
- 在现有集合上可预加载
- 自定义名称
就像真实的关系一样!