Skip to main content
Version: 0.7.0

Modeling API Reference

Complete reference for struct tags, relations, hooks, and model metadata.

Struct Tags

db - Column Mapping

type User struct {
ID int64 `db:"id"` // Column name
FirstName string `db:"first_name"` // Explicit column name
Internal string `db:"-"` // Ignored (not persisted)
}

pk - Primary Key

// Single primary key
type User struct {
ID int64 `db:"id" pk:"true"`
}

// Composite primary key
type Membership struct {
UserID int64 `db:"user_id" pk:"true"`
GroupID int64 `db:"group_id" pk:"true"`
}

rel - Relations

type User struct {
ID int64 `db:"id" pk:"true"`
Posts []Post `rel:"has_many" join:"user_id"` // One-to-many
Profile Profile `rel:"has_one" join:"user_id"` // One-to-one
}

type Post struct {
ID int64 `db:"id" pk:"true"`
UserID int64 `db:"user_id"`
User *User `rel:"belongs_to" join:"user_id"` // Many-to-one
}

type Product struct {
ID int64 `db:"id" pk:"true"`
Tags []Tag `rel:"m2m" m2m:"product_tags:product_id:tag_id"` // Many-to-many
}

Relation Types:

TypeDirectionFK LocationTag
has_oneOne-to-oneRelated tablerel:"has_one" join:"fk_col"
has_manyOne-to-manyRelated tablerel:"has_many" join:"fk_col"
belongs_toMany-to-oneThis tablerel:"belongs_to" join:"fk_col"
m2mMany-to-manyJoin tablerel:"m2m" m2m:"join_table:this_fk:other_fk"

quark - Constraints

type User struct {
ID int64 `db:"id" pk:"true"`
Email string `db:"email" quark:"unique,not_null"`
Name string `db:"name" quark:"not_null"`

// Column rename for migrations
NewField string `db:"new_field" quark:"rename:old_field"`
}
OptionDescription
not_nullNOT NULL constraint
uniqueUNIQUE constraint
rename:oldRename column during sync

default - Default Values

type User struct {
Status string `db:"status" default:"'active'"`
Count int `db:"count" default:"0"`
}

nullable - Null Handling

type User struct {
// Explicitly allow NULL
DeletedAt *time.Time `db:"deleted_at" nullable:"true"`

// Explicitly disallow NULL
Email string `db:"email" nullable:"false"`
}

Soft Delete

type User struct {
ID int64 `db:"id" pk:"true"`
Name string `db:"name"`
DeletedAt *time.Time `db:"deleted_at"` // Enables soft delete
}

// Query excludes soft-deleted by default
users, _ := quark.For[User](ctx, client).List()

// Include soft-deleted with Unscoped
allUsers, _ := quark.For[User](ctx, client).Unscoped().List()

Hooks

BeforeCreateHook

func (u *User) BeforeCreate(ctx context.Context) error {
u.CreatedAt = time.Now()
if u.Status == "" {
u.Status = "pending"
}
return nil
}

AfterCreateHook

func (u *User) AfterCreate(ctx context.Context) error {
// Send welcome email, index in search, etc.
return eventBus.Publish(ctx, "user.created", u.ID)
}

BeforeUpdateHook

func (u *User) BeforeUpdate(ctx context.Context) error {
u.UpdatedAt = time.Now()
return nil
}

AfterUpdateHook

func (u *User) AfterUpdate(ctx context.Context) error {
// Invalidate cache, sync to external systems
return cache.Invalidate(ctx, fmt.Sprintf("user:%d", u.ID))
}

BeforeDeleteHook

func (u *User) BeforeDelete(ctx context.Context) error {
// Clean up related resources
return cleanupUserFiles(u.ID)
}

AfterDeleteHook

func (u *User) AfterDelete(ctx context.Context) error {
// Audit logging
return audit.Log(ctx, "user.deleted", u.ID)
}

Custom Table Name

type User struct {
ID int64 `db:"id" pk:"true"`
Name string `db:"name"`
}

func (User) TableName() string {
return "app_users" // Custom table name
}

Metadata Access

meta := quark.GetModelMeta[User]()

fmt.Println(meta.Table) // "users"
fmt.Println(meta.PK.Column) // "id"
fmt.Println(meta.HasCompositePK) // false

for _, field := range meta.Fields {
fmt.Printf("%s -> %s\n", field.Column, field.Type)
}

for name, rel := range meta.Relations {
fmt.Printf("%s: %s via %s\n", name, rel.Type, rel.JoinCol)
}