PHPackages                             thytanium/eloquent-positionable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. thytanium/eloquent-positionable

ActiveLibrary[Database &amp; ORM](/categories/database)

thytanium/eloquent-positionable
===============================

Use a position property to sort Eloquent models

v0.2.0(3y ago)117[2 issues](https://github.com/thytanium/eloquent-positionable/issues)MITPHPPHP ^8.0

Since Dec 6Pushed 3y ago1 watchersCompare

[ Source](https://github.com/thytanium/eloquent-positionable)[ Packagist](https://packagist.org/packages/thytanium/eloquent-positionable)[ RSS](/packages/thytanium-eloquent-positionable/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (5)Versions (4)Used By (0)

thytanium/eloquent-positionable
===============================

[](#thytaniumeloquent-positionable)

[![Tests](https://github.com/thytanium/eloquent-positionable/actions/workflows/test.yml/badge.svg)](https://github.com/thytanium/eloquent-positionable/actions/workflows/test.yml/badge.svg)[![Latest Stable Version](https://camo.githubusercontent.com/b930a05ed20eaa1050f8570e05f4c6d63f071828f13061892629678094fae44f/687474703a2f2f706f7365722e707567782e6f72672f74687974616e69756d2f656c6f7175656e742d706f736974696f6e61626c652f76)](https://packagist.org/packages/thytanium/eloquent-positionable)[![Total Downloads](https://camo.githubusercontent.com/822b4d5c67c0e5bf4648daf66b4948e671aeb114441b4c23ace3b41722d932df/687474703a2f2f706f7365722e707567782e6f72672f74687974616e69756d2f656c6f7175656e742d706f736974696f6e61626c652f646f776e6c6f616473)](https://packagist.org/packages/thytanium/eloquent-positionable)[![PHP Version Require](https://camo.githubusercontent.com/9b96a0713b387e246d7afa0e1d791b28d413858bbd507b8c08d58ea781a1e2e8/687474703a2f2f706f7365722e707567782e6f72672f74687974616e69756d2f656c6f7175656e742d706f736974696f6e61626c652f726571756972652f706870)](https://packagist.org/packages/thytanium/eloquent-positionable)[![License](https://camo.githubusercontent.com/ab3c86d9e3a5d9cc1b9bc13ed9e5097c4e1b15f10e2bf7de5709bbf93a246302/687474703a2f2f706f7365722e707567782e6f72672f74687974616e69756d2f656c6f7175656e742d706f736974696f6e61626c652f6c6963656e7365)](https://packagist.org/packages/thytanium/eloquent-positionable)

Use a property to sort Eloquent models.

This is a zero-config package that provides a trait to handle positioning/sorting capabilities for Eloquent models.

Compatibility
-------------

[](#compatibility)

**PHP &gt;= 8.0** and **Laravel &gt;= 8.0**.

Installation
------------

[](#installation)

This package can be installed through composer.

> Don't worry about service providers. This package doesn't expose service providers.

```
composer require thytanium/eloquent-positionable
```

Usage
-----

[](#usage)

- Add the trait `Thytanium\EloquentPositionable\Positionable` to your model.
- Optionally, specify the column name.
    - If no column name is provided, the column `position` will be used for positioning models.

```
use Illuminate\Database\Eloquent\Model;
use Thytanium\EloquentPositionable\Positionable;

class MyModel extends Model
{
    use Positionable;

    // optional parameters
    protected $positionable = [
        'column' => 'column_name', // column used for positioning
        'start' => 5, // starting position
    ];
}
```

Creating a new model will automatically assign the next available position.

```
$myModel = new MyModel();
$myModel->save();

$myModel->getPosition(); // by default will return 1, or the custom starting position
```

API
---

[](#api)

### Sorting

[](#sorting)

#### `moveTo(int $position)`

[](#movetoint-position)

Moves the model to the indicated position.

```
$model->moveTo(5); // moves model to position 5
```

#### `moveToStart()`

[](#movetostart)

Moves the model to the start.

```
$model->moveToStart();
```

#### `moveToEnd()`

[](#movetoend)

Moves the model to the end.

```
$model->moveToEnd();
```

#### `moveUp(?int $places = 1)`

[](#moveupint-places--1)

Moves the model the indicated amount of places up. Default `1`.

```
$model->moveUp(); // moves the model 1 place up
$model->moveUp(5); // moves the model 5 places up
```

#### `moveDown(?int $places = 1)`

[](#movedownint-places--1)

Moves the model the indicated amount of places down. Default `1`.

```
$model->moveDown(); // moves the model 1 place down
$model->moveDown(5); // moves the model 5 places down
```

#### `moveStep(int $step)`

[](#movestepint-step)

Moves the model by position change (step). A positive values moves the model up. A negative value moves the model down.

```
$model->moveStep(-1); // moves the model 1 place up
$model->moveStep(1); // moves the model 1 place down
```

#### `setNewOrder(array $ids, int $startPosition = 1, ?string $primaryKeyColumn = null)`

[](#setneworderarray-ids-int-startposition--1-string-primarykeycolumn--null)

Sets a new order for the specified ids.

```
Model::setNewOrder([1, 2, 3]); // sets sequencial order on models with ids 1, 2 and 3 starting from position 1
Model::setNewOrder([1, 2, 3], 5); // sets sequencial order on models with ids 1, 2 and 3 starting from position 5
```

### Querying

[](#querying)

#### `ordered($order = 'asc'): \Illuminate\Database\Eloquent\Builder`

[](#orderedorder--asc-illuminatedatabaseeloquentbuilder)

Query scope to sort models by their position, i.e get the sorted list.

```
MyModel::ordered()->get(); // get all models in ascending order
MyModel::ordered('desc')->get(); // get all models in descending order
```

#### `position(int $position): \Illuminate\Database\Eloquent\Builder`

[](#positionint-position-illuminatedatabaseeloquentbuilder)

Query scope to search models with position equal to `$position`.

```
MyModel::position(1)->first(); // get the model at the start
```

#### `positionBetween(array $between): \Illuminate\Database\Eloquent\Builder`

[](#positionbetweenarray-between-illuminatedatabaseeloquentbuilder)

Query scope to search models with position between 2 values.

```
MyModel::positionBetween([1, 9])->get(); // get models between positions 1 and 9
MyModel::positionBetween([1, 9])->ordered()->get(); // get models in ordered fashion between positions 1 and 9
```

### Swaping

[](#swaping)

#### `swapPositions(\Illuminate\Database\Eloquent\Model|int $target)`

[](#swappositionsilluminatedatabaseeloquentmodelint-target)

Swap positions with another model or position.

```
$model1->swapPositions($model2); // swap position with another model instance
$model1->swapPositions(2); // swap position with whichever model holds position 2
```

Groups
------

[](#groups)

In the case your model has grouping fields, like `user_id`, it can be taken care of by indicating the grouping column names:

```
use Illuminate\Database\Eloquent\Model;
use Thytanium\EloquentPositionable\Positionable;

class MyModel extends Model
{
    use Positionable;

    // optional parameters
    protected $positionable = [
        'column' => 'column_name', // column used for positioning
        'start' => 5, // starting position
        'groups' = ['user_id'], // columns for grouping
    ];
}
```

##### Example

[](#example)

iduser\_idposition111212313421Caveats
-------

[](#caveats)

Although this trait makes sure the same position is not used by more than one model, do not add a `UNIQUE` index to the position column. This will be overcome in future releases.

Tests
-----

[](#tests)

The package contains unit/integration tests set up with PHPUnit.

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG.md](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

Alternatives
------------

[](#alternatives)

- [spatie/eloquent-sortable](https://github.com/spatie/eloquent-sortable)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance0

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~204 days

Total

3

Last Release

1207d ago

PHP version history (3 changes)v0.1PHP &gt;=7.3

v0.1.1PHP ^7.3|^8.0

v0.2.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/8ac4e3c75a8b6ccf804c6318180c4d8246f215852da188e2a050f1684fbe2d32?d=identicon)[thytanium](/maintainers/thytanium)

---

Top Contributors

[![aleaugustog](https://avatars.githubusercontent.com/u/1444898?v=4)](https://github.com/aleaugustog "aleaugustog (9 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/thytanium-eloquent-positionable/health.svg)

```
[![Health](https://phpackages.com/badges/thytanium-eloquent-positionable/health.svg)](https://phpackages.com/packages/thytanium-eloquent-positionable)
```

###  Alternatives

[watson/validating

Eloquent model validating trait.

9723.3M47](/packages/watson-validating)[cybercog/laravel-love

Make Laravel Eloquent models reactable with any type of emotions in a minutes!

1.2k302.7k1](/packages/cybercog-laravel-love)[cviebrock/eloquent-taggable

Easy ability to tag your Eloquent models in Laravel.

567694.8k3](/packages/cviebrock-eloquent-taggable)[clickbar/laravel-magellan

This package provides functionality for working with the postgis extension in Laravel.

423715.4k1](/packages/clickbar-laravel-magellan)[genealabs/laravel-pivot-events

This package introduces new eloquent events for sync(), attach(), detach() or updateExistingPivot() methods on BelongsToMany relation.

1404.9M8](/packages/genealabs-laravel-pivot-events)[reedware/laravel-relation-joins

Adds the ability to join on a relationship by name.

2121.2M13](/packages/reedware-laravel-relation-joins)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
