Model Definition
Define tables, columns, indexes, hidden fields, and model-level behavior without struct tags.
Models implement Define(*oro.SchemaBuilder). Field names are Go struct field names; column names default to snake case.
type User struct {
oro.Model
softdelete.SoftDeleteFields
Email string
PasswordHash string
Status string
Profile oro.JSONRaw
}
func (User) Define(s *oro.SchemaBuilder) {
s.Table("users")
s.Field("Email").String().Size(160).Unique()
s.Field("PasswordHash").Column("password_hash").String().Hidden()
s.Field("Status").Enum("active", "disabled").Default("active").Index()
s.Field("Profile").JSON().Nullable()
}
oro.Model contains id, created_at, and updated_at. Add softdelete.SoftDeleteFields from extensions/softdelete only when the model needs soft delete; it maps DeletedAt to deleted_at.
Naming rules
| Item | Default | Override |
|---|---|---|
| Table | snake-case model name plus s |
s.Table("users") |
| Column | snake-case field name | s.Field("PasswordHash").Column("password_hash") |
| JSON output | Go JSON tags and serializer rules | relation JSONName(...), normal struct tags |
Field types
s.Field("Name").String().Size(120)
s.Field("Description").Text()
s.Field("Enabled").Bool().Default(true)
s.Field("Quantity").Int()
s.Field("Views").BigInt()
s.Field("Price").Decimal(12, 2).Default(0)
s.Field("Ratio").Float()
s.Field("Payload").Binary()
s.Field("Meta").JSON().Nullable()
s.Field("UUID").UUID()
s.Field("CreatedAt").Timestamp()
s.Field("Birthday").Date()
s.Field("SendAt").Time()
s.Field("Status").Enum("draft", "published")
Oro also provides semantic aliases such as Email, URL, IP, MAC, Phone, Slug, Color, StringArray, IntArray, and Point. They keep the model definition expressive while each dialect maps them to supported database types.
Null values
Use oro.Null[T] when you need a nullable value that is still easy to read and serialize.
type Product struct {
oro.Model
Stock oro.Null[int] `json:"stock"`
}
product.Stock = oro.NullOf(10) // valid value
product.Stock = oro.NullZero[int]() // SQL NULL
This avoids pointer-heavy code like *int for normal nullable fields.
Defaults, only, and omit
s.Field("Price").Uint().Default(0)
s.Field("CreatedAt").Timestamp().DefaultExpr("CURRENT_TIMESTAMP")
For writes, control submitted fields explicitly:
db.Use[Product]().Create(ctx, product, oro.Only("Code", "Price"))
db.Use[Product]().Update(ctx, oro.Map{"Price": 120}, oro.Omit("UpdatedAt"))
Only means only these fields are written. Omit means these fields are excluded, allowing database defaults or existing values to apply.
Indexes
s.Field("Code").Unique()
s.Field("Status").Index()
s.Field("Title").FullText()
s.Index("idx_posts_status", "Status")
s.Unique("uk_posts_slug", "Slug")
s.FullText("ft_posts_title_body", "Title", "Body")
Hidden and virtual fields
s.Field("PasswordHash").Hidden()
s.Field("CommentsCount").Virtual()
Hidden fields are excluded from default select and serialization. Virtual fields are never synced as database columns and are useful for aggregates such as WithCount.
Model-level options
func (Order) Define(s *oro.SchemaBuilder) {
s.Table("orders")
s.Connection("mysql")
s.Shard("orders", "TenantID")
}
Connectionsets the default connection for this model.Shardmaps model queries to a shard group. Tenant-specific model options are documented in the Tenant Extension.