Models
A model represents one database table. It carries metadata (table name, primary key, columns) and inherits query-builder methods from ORM::OModel.
BaseModel
Place your models under app/models/. A minimal model:
// app/models/Post.h
#pragma once
#include "orm/omodel.h"
class Post : public ORM::OModel
{
public:
Post() {
table = "posts";
primaryKey = "id";
public_columns = {"id", "title", "body", "user_id", "created_at"};
private_columns = {};
}
};
Relations
Builder exposes four relation helpers that OModel inherits:
hasOne(model, foreignKey, localKey)hasMany(model, foreignKey, ownerKey)belongsTo(model, foreignKey, ownerKey)belongsToMany(model, pivotTable, foreignKey, ownerKey)
Each one schedules a join that gets resolved when you call get(). They mirror the relation API you may know from Laravel.
User u;
auto posts = u.find(42).hasMany(Post{}, "user_id", "id").get();
Model update pipeline
The typed pipeline (Model::query<T>(), TypedQuery<T>) hydrates rows into real model instances and closes the full CRUD loop — load, mutate, save() emits an UPDATE keyed on the hydrated id:
// Load, mutate, save
User u = User::query<User>()
->where("email", email)
->firstOrFail();
u.set("last_login", now);
u.save(); // UPDATE users SET ... WHERE id=<hydrated>
// By id
User u = User::findAs<User>(id); // throws if missing
auto opt = User::tryFindAs<User>(id);
// Instance DELETE
u.remove(); // DELETE FROM users WHERE id=<hydrated>
// Bulk (guarded — empty WHERE throws)
// Status transition (state machine on a cohort)
Invoice::query<Invoice>()->where("status","=","pending")
->update();
// Soft-delete on a coherent cohort
User::query<User>()->where("banned","=", true)
->update(); // soft-delete
// Hard-delete the same cohort
User::query<User>()->where("banned","=", true)
->remove(); // hard delete
See ORM → TypedQuery for the full API surface, terminal cheat sheet, guards and BC notes.