Traits & Reuse
- When logic is reused across classes, place it in a Trait
- No copy/paste logic, no duplication across components
- A trait is for behavior that operates on
$this. A pure function that only transforms its arguments — formatting or normalizing a value — belongs in a helper, because a trait would make it a method of every class that uses it - Trait location by type:
- Model traits →
app/Traits/(App\Traits) - Livewire traits →
app/Livewire/Traits/(App\Livewire\Traits)
- Model traits →
- When a trait encapsulates a feature, keep that feature self-contained: properties, relationships, scopes, methods, and any trait-owned observer registration via
bootTraitName(). Model-specific observers keep only behavior unique to that model. - Name a feature trait after the feature it encapsulates —
HasReferralsfor the referral feature — and use it in the model that owns the feature. - Extract feature traits only for features a model has but is not. Do not move a model's own domain methods into a trait just to satisfy the count.