-
Notifications
You must be signed in to change notification settings - Fork 75
Type aggregate properties: withSum, withAvg, withMin, withMax, withExists #644
Description
Problem
After calling withSum(), withAvg(), withMin(), withMax(), or withExists(), Laravel dynamically adds properties to the model following the pattern {relation}_{function}_{column}. These are currently unresolved by the plugin.
$user = User::withCount('posts')
->withSum('posts', 'views')
->withAvg('posts', 'rating')
->withExists('posts')
->first();
$user->posts_count; // ❌ unresolved (see #503)
$user->posts_sum_views; // ❌ unresolved
$user->posts_avg_rating; // ❌ unresolved
$user->posts_exists; // ❌ unresolvedExpected types
| Method | Property pattern | Type |
|---|---|---|
withCount |
{rel}_count |
int<0, max> |
withSum |
{rel}_sum_{col} |
numeric-string|null |
withAvg |
{rel}_avg_{col} |
numeric-string|null |
withMin |
{rel}_min_{col} |
string|null |
withMax |
{rel}_max_{col} |
string|null |
withExists |
{rel}_exists |
bool |
Also covers loadCount, loadSum, loadAvg, loadMin, loadMax, loadExists on the Model.
Implementation ideas
Two complementary approaches:
-
Static property provider — extend
ModelRelationshipPropertyHandlerto recognize_countsuffix (strip → find relation → returnint<0, max>). This works without seeing thewithCount()call, purely from the property name pattern + model's relation methods. -
Flow-sensitive tracking (ambitious) — an
AfterMethodCallAnalysisInterfacehandler that observeswithSum('posts', 'views')calls and records the resulting property name + type. This enables precise typing for_sum_*,_avg_*, etc. where the property name depends on both the relation and column arguments.
Approach 1 is sufficient for _count and _exists. Approach 2 is needed for _sum_*, _avg_*, _min_*, _max_*.
Related
- withCount() aggregate accessors not resolved as magic properties #503 —
withCount()aggregate accessors not resolved