Overview
Every time an Eloquent model is instantiated it runs two phases: boot (once per class) and initialize (once per instance). When you define specific methods in a trait, Eloquent automatically discovers and calls them. Adding the trait to a model is all that’s needed. Laravel itself uses this pattern extensively in traits likeSoftDeletes, HasUuids, and HasUlids.
boot vs. initialize
Naming Conventions
bootXxx()
Define astatic method prefixed with boot followed by the trait’s class basename. Eloquent calls it once per class lifecycle.
initializeXxx()
Define an instance method prefixed withinitialize followed by the trait’s class basename. Eloquent calls it every time a new instance is created.
PHP Attributes
Since Laravel 12, you can use PHP Attributes instead of relying on naming conventions.Using PHP Attributes frees your method names from the trait-name constraint. You can also define multiple
#[Boot] or #[Initialize] methods within the same trait.Practical Examples
Adding a Global Scope Automatically
Merging Default Casts
Auto-archiving on Delete
Examples in the Framework
Laravel’s own traits demonstrate the pattern clearly:
Reading these implementations is a great way to understand the pattern in depth.
Caveats
Clearing Booted Models in Tests
Becauseboot* runs only once per class, tests that alter model behavior may need to reset the boot cache:
Execution Order
When a model uses multiple traits,bootXxx() and initializeXxx() are called in PHP’s trait resolution order (declaration order). Be mindful of ordering when traits depend on each other.
Summary
Implementing
bootXxx() and initializeXxx() in a trait lets you inject behavior into any Eloquent model with a single use statement — the go-to pattern for package authors.