-
Notifications
You must be signed in to change notification settings - Fork 75
SoftDeletes methods (onlyTrashed, withTrashed) fail on base Builder instances #635
Description
Problem
SoftDeletes trait declares @method static for withTrashed(), onlyTrashed(), and withoutTrashed(). These work for static model calls (Member::onlyTrashed()) via Psalm's pseudo_static_methods, but fail on builder instances:
User::query()
->whereHas('payment_method', fn(Builder $q) => $q->whereNull('deleted_at'))
->onlyTrashed() // ❌ UndefinedMagicMethod
->get();At runtime, SoftDeletingScope registers these as Builder macros via Builder::macro(), so they work on any Builder instance. Psalm doesn't know about this.
Context
PR #632 fixed this for models with custom builders by detecting @method static annotations returning Builder<static> and registering them on the custom builder class. But for models using the base Builder (the common case), there's no equivalent handler.
Suggested fix
Register trait-declared builder methods (like SoftDeletes' withTrashed/onlyTrashed/withoutTrashed) on the base Builder class as well, not just custom builders. This could be done in BuilderScopeHandler or via a new handler registered for Builder::class that checks the model's pseudo_static_methods for builder-returning methods.
The tricky part is that Builder<TModel> is generic — the handler needs to resolve the model from the template parameter to know which trait methods are available.