- How do I enforce state transitions for an Eloquent model like Order or Subscription?
- Define a `StateMachine` class with `states()`, `transitions()`, and `initialState()` methods, then bind it to your model using the `HasStateMachines` trait. The package validates transitions automatically, ensuring only allowed state changes occur.
- Can I add validation logic before a state transition (e.g., check if an order is paid before shipping)?
- Yes, use guards in your transition definitions. For example, `Transition::from('paid')->to('shipped')->guard(fn ($order) => $order->isPaid())` ensures the guard condition is met before allowing the transition.
- Does this package work with Laravel 10 and PHP 8.1+?
- Yes, the package is fully compatible with Laravel 10 and PHP 8.1+. The README and tests confirm support for modern Laravel versions, so no additional configuration is needed for basic usage.
- How do I track the history of state transitions for audit purposes?
- Enable the optional `transition_history` table by publishing the migration and running it. The package automatically logs transitions to this table, which you can query via an Eloquent relationship.
- Can I trigger events (e.g., notifications, queue jobs) after a state transition?
- Absolutely. Use the `onTransition` method in your `StateMachine` class to dispatch Laravel events, queue jobs, or send notifications. For example, `Transition::from('paid')->to('shipped')->onTransition(fn ($order) => event(new OrderShipped($order))).`
- What’s the best way to test state transitions in my Laravel application?
- Test transitions using Laravel’s built-in testing tools. Mock guards and events by overriding dependencies in your tests, and verify state changes with assertions like `$order->stateMachine()->currentState()` or `$order->stateMachine()->can('transition').`
- Will this package handle concurrent state transitions safely (e.g., two users trying to update the same record)?
- The package itself doesn’t include built-in concurrency controls, but you can implement optimistic locking via Eloquent’s `increment()` or `lockForUpdate()` methods. For critical workflows, consider adding application-level guards or database transactions.
- Is there a performance impact if I enable transition history for high-frequency models?
- Yes, the history table adds write overhead. For models with frequent transitions (e.g., real-time systems), evaluate whether you need the history table or if Laravel’s activity logging or event queues suffice for your audit requirements.
- Can I customize the storage for transition history (e.g., use a different database or cache)?
- The package uses Eloquent’s default storage for history, but you can extend it by overriding the `transitionHistory()` method in your `StateMachine` class or implementing a custom storage adapter for non-database solutions.
- What alternatives exist if I need simpler state management without guards or history?
- For basic state management, consider Laravel’s policy system or custom traits. If you need lightweight state tracking, packages like `spatie/activitylog` can complement or replace history tables. However, this package is ideal if you require declarative transitions with guards and events.