Skip to content
OpenCloseEsc
Tips
  • Laravel
  • enums
  • architecture

Rules about a status live in the status

canBeCancelled() and isFinal() as methods on the enum turn a three-way string compare copied in four places into one method in one place.

1 min read

An if that checks "pending or paid" tends to get copied: the controller, the action, the Blade button, the admin policy. When a status is added, one of the copies is missed.

enum OrderStatus: string
{
    case Pending = 'pending';
    case Paid = 'paid';
    case Shipped = 'shipped';
    case Delivered = 'delivered';
    case Cancelled = 'cancelled';
 
    public function canBeCancelled(): bool
    {
        return in_array($this, [self::Pending, self::Paid], true);
    }
 
    public function isFinal(): bool
    {
        return in_array($this, [self::Delivered, self::Cancelled], true);
    }
}

Then the action reads if (! $order->status->canBeCancelled()) and the button reads @if ($order->status->canBeCancelled()). The rule has a name, one home, and a test that covers all four callers at once.