# Eloquent
Lodata can 'discover' Eloquent model properties, the relationships between the models, and expose methods as operations on the models.
TIP
The Eloquent driver extends the SQL driver, so the same $filter
capabilities exist in both.
# Data model
Discovery of the data model is performed first using DBAL (opens new window) to introspect the database table, then Eloquent casts (opens new window) are used for further type specification. During requests, the Eloquent model getter/setter functions are used to refer to the properties, so any additional field processing being performed by the model will be preserved.
To discover a model the Lodata
facade can be used. For example to discover the Flight
model:
class LodataServiceProvider extends ServiceProvider
{
public function boot()
{
\Lodata::discover(\App\Models\Flight::class);
}
}
2
3
4
5
6
7
# Attributes
When using discovery Lodata will introspect the database schema to discover basic properties and types. For more control over exactly how entity sets, types and properties are discovered you can use PHP attributes on the model class. When you attach the first property attribute, the automatic discovery of attributes is disabled.
Attributes all use the Flat3\Lodata\Attributes
namespace.
Property attributes optionally support providing a source
to map an OData property name to a different
underlying field name.
Available attributes include:
- Primitive types such as
LodataBinary
,LodataString
. - Collections (
LodataCollection
), that support attaching an underlying type. - Enumerations (
LodataEnum
), that support an attached enum type such as a PHP backed enum. LodataIdentifier
to customize the entity set name.LodataTypeIdentifier
to customize the entity type name.
use App\Enums\Colours;
use Flat3\Lodata\Attributes\LodataCollection;
use Flat3\Lodata\Attributes\LodataDate;
use Flat3\Lodata\Attributes\LodataDuration;
use Flat3\Lodata\Attributes\LodataEnum;
use Flat3\Lodata\Attributes\LodataIdentifier;
use Flat3\Lodata\Attributes\LodataTypeIdentifier;
use Flat3\Lodata\Type\SByte;
use Illuminate\Database\Eloquent\Model;
#[
LodataIdentifier('flights'),
LodataTypeIdentifier('flight'),
LodataCollection(name: 'Items', underlyingType: SByte::class, source: 'items'),
LodataDate(name: 'OpenTime', source: 'open_time'),
LodataEnum(name: 'Colours', enum: Colours::class),
LodataDuration(name: 'Duration', source: 'timeDuration'),
]
class Flight extends Model
{
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Relationships
If model Flight
has a method passengers
that returns a
relationship (opens new window) to Passenger
such as hasOne, hasMany,
hasManyThrough, this can be discovered by Lodata as a navigation property on the Flights
entity set. This method
can be tagged using an attribute that will be picked up during discovery.
TIP
The same as Laravel itself, Lodata typically refers to 'entity types' in the singular form and 'entity sets' in the plural form.
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
#[LodataRelationship]
public function passengers()
{
return $this->hasMany(Passenger::class);
}
}
2
3
4
5
6
7
8
9
10
Alternatively for PHP versions that do not support attributes:
\Lodata::getEntitySet('Flights')
->discoverRelationship('passengers')
2
A navigation property now exists in the Flight
entity set for Passengers
. This enables the client to
navigate by using the navigation property in a URL similar to
http://127.0.0.1:8000/odata/Flights(1)/passengers
(opens new window)
to choose the flight with ID 1, and to get the passengers related to this flight. This navigation property can
also be used in $expand
requests.
If Lodata is able to determine the relationship cardinality it will be represented in the service metadata document.
You can customize the property name, description and whether it can be made null using attribute arguments:
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
#[LodataRelationship(name: 'Travelers', description: 'Navigate to travelers': nullable: true)]
public function passengers()
{
return $this->hasMany(Passenger::class);
}
}
2
3
4
5
6
7
8
9
10
The discoverRelationship
method supports the same arguments as the attribute:
\Lodata::getEntitySet('Flights')
->discoverRelationship('passengers', 'Travelers', 'Navigate to travelers', true)
2
# Operations
Lodata can also expose model methods as operations. The method will be called on the specific instance of the entity referenced in the URL.
# Enumerated types
Since Laravel 9 and PHP 8.1 there exists support for BackedEnum
casts in Eloquent models. For these to work
in Lodata, they must be integer backed enums and if using flags the integers must be powers of two (1,2,4,8 etc.) so
that the bitwise logic will work correctly.
# Collections
Eloquent supports using array
as a cast. Attributes with this cast will be automatically interpreted as collections
using the Edm.String
underlying type. The underlying type can be overridden after discovery.
# Repository
Some Laravel applications implement a repository (opens new window)
pattern for handling data access. Lodata can support this technique if the repository implements the
RepositoryInterface
so that it can retrieve the correct model class name using the getClass
method. For
invocation Lodata will pass the model instance as the bound parameter.
← Entity Data Model SQL →