- How do I install oddvalue/eloquent-sortable in a Laravel app?
- Install it with Composer using oddvalue/eloquent-sortable:^2.2, then add the Sortable trait to each model you want to order. Add an integer ordering column through a migration and configure the sort column and optional grouping on the model. The package has no service provider, facade, or config publishing step, so integration stays limited to the models you opt in.
- Which Laravel and PHP versions does oddvalue/eloquent-sortable support?
- The release notes for v2.2.0 do not state any Laravel or PHP compatibility changes, so check the package composer.json for the exact constraints. Confirm it covers your target stack, such as Laravel 11 or 12 with PHP 8.2 or newer, before adoption. Do not infer support from the changelog alone.
- How do I add a sortable column and trait to an Eloquent model?
- Add a nullable or zero-defaulted integer ordering column to the table, then use the Sortable trait on the Eloquent model. Define the ordering column and any group column through the model's sortable configuration. Once configured, the ordered() query scope and move helpers are available for that model.
- How do I scope sortable ordering to a group or parent record?
- Grouped ordering is configured through the model's sortable settings, typically by naming a group column such as company_id or parent_id. Reorder helpers then operate within that group rather than across the whole table. Add a composite index on the group and order columns, and test moving a record between groups because that case may require rebalancing both groups yourself.
- Can I reorder records with move before, move after, move to start, and move to end?
- The package provides move-before, move-after, move-to-start, and move-to-end helpers, plus an ordered() scope for reading records in sequence. A move rewrites multiple rows in the affected group, so its cost is linear in group size. Wrap multi-row moves in a database transaction with row locking when reorders can happen concurrently.
- Does oddvalue/eloquent-sortable support UUID or ULID primary keys?
- UUID and ULID primary key support is not confirmed by the overview or release notes, so verify it in the package source or composer constraints. The ordering column is separate from the model primary key, which helps, but helper behavior depends on how records are resolved. If native support is missing, keep ordering behind your own service wrapper before committing.
- How do I handle concurrent reorders and prevent duplicate sort positions?
- Ordering uniqueness is enforced in application code, not by a database constraint, so simultaneous drags in one group can interleave and create duplicate or gapped positions. Wrap each reorder in a transaction and lock the affected group rows with SELECT FOR UPDATE. Add a composite index on group and order columns, and test concurrent moves before relying on the helpers in production.
- How is oddvalue/eloquent-sortable different from spatie/eloquent-sortable?
- oddvalue/eloquent-sortable is an extension of spatie/eloquent-sortable, so it keeps the familiar trait-based sortable model approach. It adds helpers such as move before, move after, move to start, and move to end, along with an ordered() scope and scoped grouping. It remains a flat-list ordering tool, not a tree or drag-and-drop UI package.
- How do I migrate an existing position column and backfill ordering safely?
- Add the ordering column as nullable or zero-defaulted, then backfill it deterministically per group using a window function such as ROW_NUMBER() OVER (PARTITION BY group_column ORDER BY created_at, id). Set the column to NOT NULL after the backfill and add a composite index on the group and order columns. Run the migration in a transaction and test on a copy of production data first.
- Is oddvalue/eloquent-sortable maintained and production ready?
- Version 2.2.0 is a CI-maintenance release with dependency updates only and no source or public API changes, so upgrade risk from 2.1.x is negligible. The package is a small utility trait, which is a reasonable maintenance profile, but it appears to have a single maintainer. Pin the version, confirm the licence, and keep ordering logic behind a thin wrapper so you can replace it if needed.