E-commerce
Catalogs get reorganized. A category moves under a different parent, a department is renamed, and every URL beneath it changes — which is exactly the operation that leaves a stored path column stale.
#[Polyslug(source: 'name', scope: 'parent_id')] // same name allowed under different parents
class Category extends Model implements Sluggable
{
use HasPolyslug;
public function polyslugParent(): ?Sluggable
{
return $this->parent_id ? self::find($this->parent_id) : null; // /electronics/phones/iphone
}
}
polyslugParent()composes the ancestors' current slugs into the path on read, so renaming or reparenting a department changes every descendant URL immediately — no cascade job, no stored path to rebuild.scope: 'parent_id'letsaccessoriesexist under several departments without a-2suffix.
Every old path keeps resolving and 301s to the new one, so a catalog reorganization does
not cost the link equity the old URLs earned.
Route it with a catch-all:
Route::polyslug('/{category}', [CategoryController::class, 'show'])->where('category', '.*');
See also
- Nested (hierarchical) slugs
- Uniqueness and scope
- Gone and superseded content — for discontinued products that should point at their replacement.