Skip to content

Eloquent Resolver ​

EloquentEntitySetResolver resolves OData queries against an Eloquent model class. It is the default resolver for entity sets backed by Laravel models.

Usage ​

php
use LaravelUi5\OData\Driver\Sql\EloquentEntitySetResolver;

$builder->bindEntitySet(
    $container->getEntitySet('Products'),
    new EloquentEntitySetResolver(Product::class),
);

When using discoverModel(), this resolver is auto-bound. You do not need to create it manually.

Constructor ​

php
new EloquentEntitySetResolver(string $modelClass)
ParameterTypePurpose
$modelClassclass-string<Model>Fully qualified Eloquent model class

Supported query options ​

OptionHow it maps to Eloquent
$filterwhere() clauses via FilterToEloquent visitor — including any/all lambdas over relations (whereHas/whereDoesntHave), which the SQL resolver does not support. See Coverage by resolver
$searchLIKE '%term%' on all Edm.String properties, OR'd together
$select->select([...]) on the query
$orderby->orderBy($col, $dir) for each clause
$top->limit($n)
$skip->offset($n)
$count->count() (separate query, ignores pagination)
$expand->with([...]) eager loading
$computeEvaluated in PHP after fetch (concat, arithmetic, date functions)

Interfaces implemented ​

  • EntitySetResolverInterface — resolve() yields rows, count() returns total
  • EntityResolverInterface — resolveOne() fetches a single entity by key

Both are satisfied by the same instance, so a single binding covers collection and single-entity access.

How results are yielded ​

  • Without $expand: uses cursor() for memory-efficient streaming. Rows are yielded one at a time.
  • With $expand: uses get() because cursor() does not support eager loading. All rows are loaded into memory, then yielded.

Each row is converted to an associative array via Model::toArray().

Expand behavior ​

Simple expand (no nested options):

GET /odata/Flights?$expand=passengers

Maps to ->with(['passengers']).

Constrained expand (nested query options):

GET /odata/Flights?$expand=passengers($select=name;$top=5;$filter=age gt 18)

Maps to ->with(['passengers' => function ($q) { ... }]) with nested filter, select, orderby, top, and skip applied to the relation query. The PK and FK columns are always included in nested selects to ensure Eloquent can match relations to parent rows.