Database Model
Table-oriented persistence base class with CRUD helpers, scopes, callbacks, timestamps and soft deletes.
Purpose
Model is an abstract base for table-oriented persistence. It wraps DatabaseDriverInterface, builds QueryBuilder instances for the configured table and provides common read/write helpers. It is framework infrastructure, not a requirement for every persistence use case.
Model definition
A concrete model defines table name, primary key and optionally allowed fields, timestamps, user tracking, soft deletes, scopes and callbacks.
use Lemonade\Framework\Database\Model;
use Lemonade\Framework\Database\QueryBuilder;
final class ArticleModel extends Model
{
protected string $table = 'articles';
protected string $primaryKey = 'id';
protected array $allowedFields = [
'title',
'slug',
'body',
'published',
];
protected bool $useTimestamps = true;
protected bool $useSoftDeletes = true;
protected function scopePublished(QueryBuilder $builder): QueryBuilder
{
return $builder->where('published', 1);
}
}
Read helpers
Read APIs include all(), find(), first(), where(), exists(), countAll(), countWhere(), findMany(), cursor(), chunk(), builder(), query(), scoped() and applyScope(). Soft delete scope is applied automatically when enabled unless withDeleted() or onlyDeleted() is used.
$article = $articles->find($id);
$published = $articles->scoped('published')
->orderBy('created_at', 'DESC')
->getArray();
foreach ($articles->cursor() as $row) {
// Stream rows.
}
Write helpers
Write APIs include save(), insert(), update(), insertBatch(), updateBatch(), delete(), forceDelete(), deleteWhere(), restore(), restoreWhere(), increment(), decrement(), firstOrCreate(), updateOrCreate(), upsert() and batchUpsert(). Insert returns the generated id, null when nothing was inserted, or 0 when the driver reports success without an insert id.
$id = $articles->insert([
'title' => 'Hello',
'slug' => 'hello',
'body' => 'Article body',
'published' => 1,
]);
$articles->update($id, [
'title' => 'Updated title',
]);
Allowed fields
allowedFields filters insert/update payloads. Timestamp, user tracking and soft delete columns are added to the allowed list automatically when their features are enabled.
Callbacks
When allowCallbacks is true, model events can call protected methods listed in beforeInsert, afterInsert, beforeUpdate, afterUpdate, beforeInsertBatch, afterInsertBatch, beforeUpdateBatch, afterUpdateBatch, beforeFind, afterFind, beforeDelete and afterDelete. Callback payloads are associative arrays and may return a modified payload.
Usage boundary
Controllers should usually depend on application services. Those services may use Model for straightforward table persistence, QueryBuilder for read models or Database for custom SQL. Model is not a replacement for domain logic.