derive_form
Procedural macros for the Runique web framework.
Exposes two macros:
model!(...)— DSL to declare a SeaORM model and generate its schema#[form(...)]— attribute macro to generate a form struct from a model schema
model!(...)
Declares a database model and generates the corresponding SeaORM entity, ActiveModel,
relations, and a schema() function used by #[form(...)].
Syntax
model! {
ModelName,
table: "table_name",
pk: field_name => pk_type,
fields: {
field: Type [option1, option2, ...],
...
}
}
Minimal example
use *;
model!
Primary key types
| Syntax | Column type | Notes |
|---|---|---|
pk: id => Pk |
INTEGER (default) or BIGINT (feature big-pk) |
Auto-increment |
pk: id => i32 |
INTEGER (32-bit) |
Auto-increment |
pk: id => i64 |
BIGINT (64-bit) |
Auto-increment |
pk: id => uuid |
UUID |
No auto-increment |
// Integer PK (most common)
model!
// UUID PK
model!
Field types
| Type | SQL type | Example usage |
|---|---|---|
String |
VARCHAR(255) |
name: String [required, max_len(100)] |
text |
TEXT |
bio: text [nullable] |
i8 |
TINYINT |
score: i8 [required] |
i16 |
SMALLINT |
rank: i16 [required] |
i32 |
INTEGER |
count: i32 [required, default(0)] |
i64 |
BIGINT |
views: i64 [required, default(0)] |
f32 |
FLOAT |
rating: f32 [nullable] |
f64 |
DOUBLE |
price: f64 [required] |
bool |
BOOLEAN |
is_active: bool [required, default(true)] |
date |
DATE |
birth_date: date [nullable] |
time |
TIME |
start_time: time [nullable] |
datetime |
DATETIME |
created_at: datetime [auto_now] |
timestamp |
TIMESTAMP |
expires_at: timestamp [nullable] |
uuid |
UUID |
token: uuid [required, unique] |
json |
JSON |
metadata: json [nullable] |
blob |
BLOB |
data: blob [nullable] |
model!
Field options
| Option | Description |
|---|---|
required |
Column is NOT NULL |
nullable |
Column accepts NULL |
unique |
UNIQUE constraint |
index |
Create a database index |
default(value) |
Default value — default(0), default(true), default("draft") |
max_len(n) |
Max string length (validation + VARCHAR(n)) |
min_len(n) |
Min string length (validation) |
max(n) / max_f(n) |
Max integer / float value (validation) |
min(n) / min_f(n) |
Min integer / float value (validation) |
auto_now |
Set to NOW() on INSERT (timestamps) |
auto_now_update |
Set to NOW() on UPDATE (timestamps) |
fk(table.col, action) |
Foreign key — see section below |
label("...") |
Display label for generated forms |
help("...") |
Help text for generated forms |
model!
Foreign keys
Use the fk(table.column, action) option to declare a foreign key.
Actions: cascade, set_null, restrict, set_default, no_action
model!
Enums
The model! macro supports declaring enums directly alongside the model via the optional
enums: block. Variants are available as a Rust enum and integrate with SeaORM and the
admin form (rendered as a <select>).
Backing types
| Keyword | Storage | SeaORM type | Notes |
|---|---|---|---|
String |
Text column | DeriveActiveEnum(String) |
Default when no keyword specified |
i32 |
Integer column | DeriveActiveEnum(i32) |
|
i64 |
Bigint column | DeriveActiveEnum(i64) |
|
pg |
Native enum type | DeriveActiveEnum + db_type = "Enum" |
PostgreSQL only |
Enum syntax
enums: {
EnumName BackingType [Variant, Variant = "db_value", Variant = ("db_value", "Label"), ...]
}
Each variant can optionally specify:
= "db_value"— the value stored in the database (defaults to the variant name)= ("db_value", "Display label")— db value + label shown in the admin form
Example — String-backed enum (default)
use *;
model!
Stored as a VARCHAR column. The generated Status enum implements DeriveActiveEnum,
Display, FromStr, Default, Serialize, and Deserialize.
Example — PostgreSQL native ENUM
For PostgreSQL CREATE TYPE enums, use the pg keyword. The column type becomes
db_type = "Enum" with enum_name set to the snake_case enum name.
use *;
model!
The corresponding PostgreSQL migration must create the type before the table:
('Low', 'Medium', 'High');
('public', 'team', 'private');
SeaORM generates the correct ColumnType::Enum { name, variants } for these fields.
Variant labels in the admin
When a field uses an enum type, the admin form renders a <select> with one <option>
per variant. The displayed text is the label if provided, otherwise the db value.
enums:
Relations
The optional relations: block declares SeaORM relations on the model.
It generates the Relation enum, Related implementations, and RelationTrait used by SeaORM queries.
Relation types
| Declaration | Description |
|---|---|
belongs_to: Model via field |
This model holds the FK column |
has_many: Model |
One-to-many (inverse of belongs_to) |
has_many: Model as alias |
One-to-many with a custom relation name |
has_one: Model |
One-to-one (inverse of belongs_to) |
has_one: Model as alias |
One-to-one with a custom relation name |
many_to_many: Model through JoinTable via fk |
Many-to-many through a join table |
Example
use *;
model!
model!
model!
Many-to-many
model!
model!
Complete example — blog application
use *;
// ── Users ──────────────────────────────────────────────────────
model!
// ── Categories ─────────────────────────────────────────────────
model!
// ── Posts ──────────────────────────────────────────────────────
model!
// ── Comments ───────────────────────────────────────────────────
model!
impl_objects! — ORM manager (Django-style)
Activate the objects manager on a model to get Django-style queries:
use *;
model!
impl_objects!;
// In a handler:
async
#[form(...)]
Generates a form struct from the schema produced by model!.
use *;
model!
// Only expose title, content, excerpt, is_published — auto_now fields excluded
;
#[form] parameters
| Parameter | Required | Description |
|---|---|---|
schema |
yes | Path to the schema function generated by model! |
fields |
no | Whitelist — only include these fields |
exclude |
no | Blacklist — exclude these fields |
fields and exclude are mutually exclusive. The primary key is always excluded.
Using the form in a handler
pub async
License
MIT — part of the Runique project.