-
Type:
Question
-
Resolution: Fixed
-
Priority:
Unknown
-
Affects Version/s: None
-
Component/s: Laravel
-
None
-
Needed
-
-
None
-
None
-
None
-
None
-
None
-
None
babaduk47 has created Issue #3506: Builder::orderBy() does not handle the new SortDirection enum from Laravel 13.8 in laravel-mongodb. This Jira ticket was filed by GromNaN
Issue Text:
- Laravel-mongodb Version: 5.7.1
- PHP Version: 8.5.0
- Database Driver & Version: ext-mongodb 2.1.4 / mongodb/mongodb 2.1.2 (Laravel framework: v13.8.0)
Description:
Laravel 13.8 introduced a new `Illuminate\Database\Query\SortDirection` enum and started passing its cases (`SortDirection::Ascending` / `SortDirection::Descending`) as the `$direction` argument to `orderBy()` from several internal call paths (e.g. `latest()`, `oldest()`, `reorder()`, default Eloquent relation ordering). See laravel/framework#59865.
`MongoDB\Laravel\Query\Builder::orderBy()` overrides the base method and only normalizes string values:
https://github.com/mongodb/laravel-mongodb/blob/5.7.1/src/Query/Builder.php#L669-L687
```php
public function orderBy($column, $direction = 'asc')
{
if (is_string($direction)) {
$direction = match ($direction)
;
}
$column = (string) $column;
if ($column === 'natural')
else
{ $this->orders[$column] = $direction; } return $this;
}
```
When `$direction` is a `SortDirection` enum instance the `is_string()` branch is skipped, the enum is stored as-is in `$this->orders`, and the MongoDB PHP driver later fails to serialize it:
```
Non-backed enum SortDirection cannot be serialized for field path "_id"
```
This breaks any query that goes through an internal code path now passing the enum — `Model::latest()->first()`, `Model::oldest()`, default `created_at DESC` ordering on relations, etc.
The same handling is likely needed in any other places in the package that compare `$direction` against `'asc'`/`'desc'` strings (e.g. `removeExistingOrdersFor`, raw-order builders).
Steps to reproduce
1. Install `laravel/framework: ^13.8` together with `mongodb/laravel-mongodb: ^5.7`.
2. Define any Eloquent model on the MongoDB connection (e.g. `User`).
3. Run a query that uses an internal helper now passing the enum, or pass the enum directly:
```php
use Illuminate\Database\Query\SortDirection;
User::query()>latest()>first();
// or
User::query()>orderBy('created_at', SortDirection::Descending)>get();
```
Expected behaviour
`Builder::orderBy()` should accept `SortDirection::Ascending` / `SortDirection::Descending` and convert them to the MongoDB integer direction (`1` / `1`), the same way it normalizes the `'asc'` / `'desc'` strings — so `Model::latest()>first()` keeps working on Laravel 13.8.
Suggested fix:
```php
public function orderBy($column, $direction = 'asc')
{
if ($direction instanceof \Illuminate\Database\Query\SortDirection)
elseif (is_string($direction)) {
$direction = match ($direction)
;
}
// …unchanged…
}
```
The `SortDirection` reference must stay compatible with Laravel < 13.8 (e.g. via `class_exists()` guard or string-FQN check), since the enum does not exist in earlier versions.
Actual behaviour
The query throws:
```
Non-backed enum SortDirection cannot be serialized for field path "_id"
```
Stack trace points at the BSON serializer, called when the driver tries to encode `$this->orders`, which now contains a `SortDirection` enum instance instead of `1` / `-1`.
- is related to
-
PHPLIB-1847 Support PHP 8.6 \SortDirection where a sort direction is expected
-
- Needs Triage
-