[14.x] Add defaults() method to Eloquent models
We have a casts() method (which is the default in 2026), but there's no alternative for the attributes array (defaults)
This means feature flagging a cast is easy with casts(). but, flagging a default means overriding __construct something like:
class Subscription extends Model
{
protected $attributes = [
'cancelled' => false,
'trial_days' => 14,
];
public function __construct(array $attributes = [])
{
if (Feature::active('extended-trials')) {
$this->attributes['trial_days'] = 30;
}
parent::__construct($attributes);
}
}
I would like the ability to have a method for this, for consistency and ease of flagging, the ability to run logic at runtime, etc... So this PR adds a defaults() method as the method equivalent of $attributes:
class Subscription extends Model
{
protected function defaults(): array
{
return [
'cancelled' => false,
'trial_days' => Feature::active('extended-trials') ? 30 : 14,
'expires_at' => now()->addDays(config('billing.grace_period'))->toDateTimeString(),
];
}
}
Like $attributes, these are raw values, so they aren't cast or passed through mutators.
defaults() takes priority over the $attributes array, as casts() does vs $casts.
I can roll a trait locally if you hate this, but had to try.
I've targeted 14.x incase existing applications have a defaults method. Open to feedback and renaming etc. Feel free to complete change it style wise, but I bring the idea!