Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message
Laravel Model States

Laravel Model States Laravel Package

spatie/laravel-model-states

Add state and state machine behavior to Laravel Eloquent models. Represent each state as a class, automatically serialize to/from the database, and perform clean, explicit transitions with configurable rules—ideal for workflows like payments, orders, and approvals.

View on GitHub
Deep Wiki
Context7

State support for Eloquent models

Frequently asked questions about Laravel Model States
What Laravel and PHP versions does spatie/laravel-model-states support?
The package officially supports Laravel 9.x and PHP 8.1+. The 2.14.0 release includes a fix for PHP 8.5 trait binding issues, but Laravel 10+ compatibility is untested. Always check the [GitHub releases](https://github.com/spatie/laravel-model-states/releases) for updates.
How do I define allowed state transitions in my model?
Use the `StateConfig` class to define transitions. In your abstract state class, override `config()` and return a `StateConfig` instance with `allowedTransitions()` and `defaultState()`. For example: `return StateConfig::new()->allowedTransitions(['pending' => ['paid', 'failed']])->defaultState('pending');`
Can I use this package with Laravel queues or Octane?
The package doesn’t explicitly document support for Octane or queue workers like Horizon. State transitions are synchronous by default, so race conditions could occur in concurrent environments. Use database transactions or optimistic locking (`$model->fresh()`) to mitigate risks.
How do I migrate existing models to use State classes?
Add the `HasStates` trait and define the cast in `$casts`. For legacy data, ensure the serialized state string matches your new `State` class’s expected format. If the format differs, write a migration to transform existing values or use a custom accessor.
What happens if a state transition fails during a database transaction?
The package doesn’t enforce transaction boundaries for state transitions by default. Wrap transitions in a transaction manually using `DB::transaction()` to ensure atomicity. Example: `DB::transaction(fn() => $payment->transitionTo(PaidState::class));`
Are there performance concerns with state casting in high-traffic apps?
State casting adds minimal overhead, but frequent state transitions under high load could lead to race conditions. Test with your expected traffic volume and consider optimistic locking (`$model->fresh()`) or database-level locks to prevent conflicts.
How do I share behavior across multiple states without repeating code?
Extend your abstract `State` class with shared methods. For example, define a `color()` method in the base class and override it in specific states. The package automatically handles polymorphism, so concrete states inherit and override behavior seamlessly.
What alternatives exist for implementing state machines in Laravel?
Alternatives include `spatie/laravel-state-machines` (simpler, rule-based), `verot/flux` (event-driven), or custom solutions using enums with accessors. This package stands out by combining the state pattern with Eloquent casting and class-based state logic.
How do I test state transitions in my Laravel app?
Use PHPUnit to assert state transitions. Example: `$payment = new Payment(); $payment->transitionTo(PendingState::class); $this->assertInstanceOf(PendingState::class, $payment->state);`. Test edge cases like invalid transitions or concurrent changes with `DB::beginTransaction()` and rollbacks.
What’s the deprecation policy for breaking changes in this package?
Spatie typically follows semantic versioning. Breaking changes (e.g., trait method signatures) are announced in release notes and require major version bumps. Monitor the [GitHub changelog](https://github.com/spatie/laravel-model-states/blob/main/CHANGELOG.md) for deprecations, especially if upgrading from older versions.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai