Skip to content

Attribute Casting

ElasticBridge supports Eloquent-style attribute casting. Declare a $casts array (or a casts() method) on a bridge, and stored document values are converted to rich PHP types on access, back to storable values on write, and normalized in toArray()/toJson().

php
<?php

namespace App\Bridges;

use App\Enums\Currency;
use Lacasera\ElasticBridge\ElasticBridge;

class Product extends ElasticBridge
{
    protected $index = 'products';

    protected $casts = [
        'in_stock'     => 'boolean',
        'price'        => 'decimal:2',
        'published_at' => 'datetime',
        'currency'     => Currency::class, // backed enum
    ];
}
php
$product = Product::find(1);

$product->in_stock;     // bool
$product->price;        // "19.99" (string, 2 dp)
$product->published_at; // Carbon instance
$product->currency;     // Currency enum

Supported cast types

CastResult
array, jsonarray
objectstdClass
collectionIlluminate\Support\Collection
booleanbool
integerint
real, float, doublefloat
decimal:<n>string with n decimals
stringstring
dateCarbon (start of day)
datetime, datetime:<format>Carbon
immutable_date, immutable_datetimeCarbonImmutable
timestampint (unix timestamp)
encrypted, encrypted:array, encrypted:collection, encrypted:objectdecrypted value
hashedstored hash (write-only transform)
BackedEnum::classthe enum instance
AsStringable::classIlluminate\Support\Stringable
AsArrayObject::classArrayObject
AsCollection::class, AsCollection::of(...)Collection
AsEnumCollection::of(...), AsEnumArrayObject::of(...)enum collection
Custom cast (CastsAttributes)whatever the cast returns

The class-based casts (As*) are Laravel's own — reference them directly from Illuminate\Database\Eloquent\Casts.

Dates

Dates cast to Carbon. The default serialized format is ISO-8601; override globally with a $dateFormat property, or per-attribute with datetime:<format>:

php
protected $dateFormat = 'Y-m-d H:i:s';

protected $casts = [
    'released_on'  => 'date:Y-m-d',
    'published_at' => 'datetime',
];

Enums

Backed enums cast to and from their backing value. Store an array of enum values with AsEnumCollection:

php
use App\Enums\Currency;
use Illuminate\Database\Eloquent\Casts\AsEnumCollection;

protected $casts = [
    'currency'   => Currency::class,
    'currencies' => AsEnumCollection::of(Currency::class),
];

Encrypted & hashed

encrypted* casts use Laravel's encrypter; hashed uses the hasher (a one-way, write-time transform).

Search implications

Encrypted values are opaque ciphertext in the index — you cannot search or aggregate on encrypted fields. hashed is one-way (useful for storing secrets you only verify, never read back). Prefer these only for fields you never query.

Custom casts

Implement Laravel's Illuminate\Contracts\Database\Eloquent\CastsAttributes (or CastsInboundAttributes, Castable, SerializesCastableAttributes).

Bridges are not Eloquent models

Write your cast's $model parameter untyped (or type it as your bridge). A bridge is not an Illuminate\Database\Eloquent\Model, so a strict Model $model type hint will throw. Laravel's own built-in cast classes already use an untyped $model, so they work as-is.

php
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class AsAddress implements CastsAttributes
{
    public function get(
        $model,
        string $key,
        $value,
        array $attributes,
    ): Address {
        return new Address(
            $attributes['line_one'],
            $attributes['line_two'],
        );
    }

    public function set(
        $model,
        string $key,
        $value,
        array $attributes,
    ): array {
        return [
            'line_one' => $value->lineOne,
            'line_two' => $value->lineTwo,
        ];
    }
}

Note on JSON casts and Elasticsearch

The array/json/object/collection casts store native arrays/objects in the document (so the fields remain queryable in Elasticsearch/OpenSearch), rather than the JSON-encoded strings Eloquent writes to a relational column.

Nested fields

Casts can target nested fields using dot notation ('hotel.location.lat' => 'float'). See Nested Attributes for the full details on casting, accessors, mutators, and serialization of nested paths.

Released under the MIT License.