spatie/eloquent-sortable

repository·main·Indexed 23 days ago

https://github.com/spatie/eloquent-sortable

A Laravel package that provides a trait to add sortable behavior to Eloquent models. It allows for the management of record ordering via an order column, providing an ordered() query scope, methods to move individual models (moveOrderUp, moveOrderDown, moveToStart, moveToEnd), and the ability to reorder records using setNewOrder or setNewOrderByCustomColumn.

Tokens
2K
Snippets
11
Records
13
Agent score
31%

What's inside spatie/eloquent-sortable

  1. Implement grouping for sortable models

    main

    If your sorting should be scoped to a specific group (e.g., a user_id), implement the buildSortQuery method in your model. This method should return a query builder that includes the necessary constraints to restrict sorting calculations to that group.

    // MyModel.php
    
    public function buildSortQuery()
    {
        return static::query()->where('user_id', $this->user_id);
    }
  2. Register the Service Provider

    main

    In Laravel 5.5 and above, the service provider is automatically registered. For older versions, manually add the provider to your config/app.php file.

    'providers' => [
        ...
        Spatie\EloquentSortable\EloquentSortableServiceProvider::class,
    ];
  3. Add sortable behaviour to an Eloquent model

    main

    To make a model sortable, you must:

    1. Implement the Spatie\EloquentSortable\Sortable interface.
    2. Use the Spatie\EloquentSortable\SortableTrait trait.
    3. (Optional) Define a $sortable property to override default configuration settings like order_column_name or sort_when_creating.
    use Spatie\EloquentSortable\Sortable;
    use Spatie\EloquentSortable\SortableTrait;
    
    class MyModel extends Model implements Sortable
    {
        use SortableTrait;
    
        public $sortable = [
            'order_column_name' => 'order_column',
            'sort_when_creating' => true,
        ];
    
        // ...
    }
  4. Configure eloquent-sortable settings

    main

    The published configuration file contains the following keys:

    • order_column_name: The name of the column used to sort models (default: order_column).
    • sort_when_creating: Boolean determining if the package should automatically assign the highest order number to new models (default: true).
    • ignore_timestamps: Boolean determining if updated_at should be ignored when using setNewOrder (default: false).
    return [
      /*
       * The name of the column that will be used to sort models.
       */
      'order_column_name' => 'order_column',
    
      /*
       * Define if the models should sort when creating. When true, the package
       * will automatically assign the highest order number to a new model
       */
      'sort_when_creating' => true,
    
      /*
       * Define if the timestamps should be ignored when sorting.
       * When true, updated_at will not be updated when using setNewOrder
       */
      'ignore_timestamps' => false,
    ];
  5. Set a new order using a custom column with `setNewOrderByCustomColumn`

    main

    If you need to sort based on a column other than the primary key (e.g., a UUID), use setNewOrderByCustomColumn.

    Arguments:

    1. string $column: The name of the custom column.
    2. array $values: An array of values from that column in the desired order.
    3. int $startingOrder (optional): The integer value to start the ordering from.
    // Using UUIDs instead of primary keys
    MyModel::setNewOrderByCustomColumn('uuid', [
       '7a051131-d387-4276-bfda-e7c376099715',
       '40324562-c7ca-4c69-8018-aff81bff8c95',
       '5dc4d0f4-0c88-43a4-b293-7c7902a3cfd1'
    ]);
    
    // Using UUIDs with a starting order of 10
    MyModel::setNewOrderByCustomColumn('uuid', [
       '7a051131-d387-4276-bfda-e7c376099715',
       '40324562-c7ca-4c69-8018-aff81bff8c95',
       '5dc4d0f4-0c88-43a4-b293-7c7902a3cfd1'
    ], 10);
  6. Set a new order for all records using `setNewOrder`

    main

    Use setNewOrder to reorder all records in the model based on an array of IDs.

    Arguments:

    1. array $ids: An array of model IDs in the desired order.
    2. int $startingOrder (optional): The integer value to start the ordering from.
    3. mixed $query (optional): A query instance or null.
    4. callable $queryModifier (optional): A closure to modify the query (e.g., to remove global scopes).
  7. Listen for the `EloquentModelSortedEvent`

    main

    The package dispatches a Spatie\EloquentSortable\EloquentModelSortedEvent after a sort operation completes. You can listen for this event to perform post-sorting actions like clearing caches. Use the isFor() helper on the event to check which class was sorted.

    use Spatie\EloquentSortable\EloquentModelSortedEvent as SortEvent;
    
    class SortingListener
    {
        public function handle(SortEvent $event): void {
            if ($event->isFor(MyClass::class)) {
                // Perform post-sorting logic, e.g., flush cache
            }
        }
    }
  8. Move individual models in order

    main

    The SortableTrait provides several methods to manipulate the order of a single model instance:

    • $model->moveOrderDown(): Moves the model one position down.
    • $model->moveOrderUp(): Moves the model one position up.
    • $model->moveToStart(): Moves the model to the first position.
    • $model->moveToEnd(): Moves the model to the last position.
    • $model->isFirstInOrder(): Returns true if the model is currently first.
    • $model->isLastInOrder(): Returns true if the model is currently last.
    $myModel->moveOrderDown();
    $myModel->moveOrderUp();
    
    $myModel->moveToStart();
    $myModel->moveToEnd();
    
    $myModel->isFirstInOrder();
    $myModel->isLastInOrder();