Code Generation
forge uses AST-based code generation to create type-safe code from your schema definitions.
How It Works​
- Parse Models - AST parser reads your Go model files
- Extract Schema - Extracts field definitions, relations, meta, hooks
- Generate Code - Creates type-safe managers, querysets, and field expressions
- Write Files - Writes generated files to
models/*.gen.go
Generated Files​
Model Struct​
models/post.gen.go:
type Post struct {
ID int64
Title string
Content string
Published bool
CreatedAt time.Time
UpdatedAt time.Time
AuthorID int64
Author *User
Categories []*Category
}
Field Expressions​
models/post_fields.gen.go:
type PostFields struct {
ID query.FieldExpr[int64]
Title query.FieldExpr[string]
Content query.FieldExpr[string]
Published query.FieldExpr[bool]
CreatedAt query.FieldExpr[time.Time]
UpdatedAt query.FieldExpr[time.Time]
}
var PostFields = PostFields{
ID: query.NewFieldExpr[int64]("id"),
Title: query.NewFieldExpr[string]("title"),
Content: query.NewFieldExpr[string]("content"),
Published: query.NewFieldExpr[bool]("published"),
CreatedAt: query.NewFieldExpr[time.Time]("created_at"),
UpdatedAt: query.NewFieldExpr[time.Time]("updated_at"),
}
Manager​
models/post_manager.gen.go:
type PostManagerType struct {
db *db.DB
}
var Post = PostManagerType{}
func (m *PostManagerType) Create(ctx context.Context, instance *Post) error {
// Create implementation
}
func (m *PostManagerType) Get(ctx context.Context, id int64) (*Post, error) {
// Get implementation
}
func (m *PostManagerType) Update(ctx context.Context, instance *Post) error {
// Update implementation
}
func (m *PostManagerType) Delete(ctx context.Context, instance *Post) error {
// Delete implementation
}
func (m *PostManagerType) Filter(conditions ...query.QueryExpr) *PostQuerySet {
// Filter implementation
}
QuerySet​
models/post_queryset.gen.go:
type PostQuerySet struct {
*query.BaseQuerySet[Post]
}
func (qs *PostQuerySet) All(ctx context.Context) ([]*Post, error) {
return qs.BaseQuerySet.All(ctx)
}
func (qs *PostQuerySet) Get(ctx context.Context, id int64) (*Post, error) {
return qs.BaseQuerySet.Get(ctx, id)
}
// ... other methods
Running Code Generation​
forge generate
This will:
- Scan
models/directory for model definitions - Parse each model file
- Generate code for each model
- Write generated files
Customizing Generation​
Custom Templates​
You can customize generation templates, though this is advanced and not recommended for most users.
Generation Options​
# Generate for specific models
forge generate --models Post,User
# Output to different directory
forge generate --output ./generated
Best Practices​
- Don't Edit Generated Files - They will be overwritten
- Regenerate After Model Changes - Always regenerate after modifying models
- Commit Generated Files - Include
*.gen.gofiles in version control - Use Type-Safe APIs - Use generated field expressions and querysets
Troubleshooting​
Generation Fails​
- Check model syntax
- Ensure all imports are correct
- Verify schema interface implementation
Generated Code Errors​
- Regenerate code
- Check for circular dependencies
- Verify model definitions
See Also​
- Models Guide - Model definitions
- Plugins - Extend code generation