Model#
Meritum\Database\Model
Abstract base class for all database-backed entities. Provides attribute storage, cast conversion, dirty tracking, and PHP 8.4 property hook integration.
Configuration Properties#
Declare these as protected properties in your subclass:
protected string $table; // required — the database table name
protected string $primaryKey = 'id';
protected string $primaryKeyType = 'string'; // 'string' or 'int'
protected bool $incrementing = false;
protected bool $timestamps = true;
protected string $createdAtColumn = 'created_at';
protected string $updatedAtColumn = 'updated_at';
protected array $casts = [];Property Hooks#
Access attributes through PHP 8.4 property hooks backed by getAttribute() and setAttribute():
public string $name {
get => $this->getAttribute('name');
set => $this->setAttribute('name', $value);
}Read-only attributes omit the set hook. Cast values are applied automatically when the column name has an entry in $casts.
Protected Methods#
protected function getAttribute(string $key): mixed;Returns the attribute value for $key, applying any registered accessor and cast.
protected function setAttribute(string $key, mixed $value): void;Stores $value for $key, applying any registered mutator before storage.
protected function accessors(): array;Override to register per-column read transformations. Return an array keyed by column name:
protected function accessors(): array
{
return [
'name' => fn(string $v) => ucwords($v),
];
}protected function mutators(): array;Override to register per-column write transformations. Return an array keyed by column name:
protected function mutators(): array
{
return [
'email' => fn(string $v) => strtolower($v),
];
}Public Methods#
public function isNew(): bool;Returns true if the model has not been persisted (has no original attributes).
public function isDirty(): bool;Returns true if any attribute has changed since the model was last synced.
public function hydrate(array $attributes): void;Populates the model from a raw database row. Throws LogicException if the model already has attributes (call hydrate() only on fresh instances).
public function toArray(): array;Returns all attributes as a plain array. DateTimeImmutable values are formatted as ISO 8601 strings. Any loaded relations are merged in after attributes; JsonSerializable relation objects have jsonSerialize() called, scalars and arrays are included as-is.
protected function setRelation(string $name, mixed $relation): void;Stores a loaded relation in the relation bag under $name. Throws LogicException if $relation is null or an object that does not implement JsonSerializable.
protected function getRelation(string $name): mixed;Returns the stored relation for $name, or null if it has not been set.
protected function hasRelation(string $name): bool;Returns true if a relation has been stored under $name.
Serialization#
Model implements PHP native serialization via __serialize()/__unserialize(). Attributes and relations are persisted; the model has no dirty state on unserialize. This makes models compatible with any cache backend that relies on serialize() (PSR-6, PSR-16, Redis, APCu).
$user = $repository->findOrFail($id);
$cache->set("user:{$id}", serialize($user));
$user = unserialize($cache->get("user:{$id}"));Callers are responsible for ensuring any relations stored on the model are themselves serializable.