Skip to main content

Lifecycle Hooks API Reference

The github.com/forgego/forge/schema package provides Django-style lifecycle hooks for intercepting, modifying, validating, or reacting to ORM persistence events.


The ModelHooks Struct​

Models register hooks by returning *schema.ModelHooks from their Hooks() method:

func (Product) Hooks() *schema.ModelHooks {
return schema.NewModelHooks().
WithBeforeCreate(beforeCreateHook).
WithAfterCreate(afterCreateHook).
WithBeforeSave(beforeSaveHook).
WithClean(cleanValidationHook)
}

Complete List of Hook Points​

Hook MethodSignatureTrigger Event
WithBeforeCreatefunc(ctx context.Context, instance any) errorImmediately before a new record is inserted into the database.
WithAfterCreatefunc(ctx context.Context, instance any) errorImmediately after a new record is successfully committed to the database.
WithBeforeUpdatefunc(ctx context.Context, instance any) errorImmediately before an existing record is updated in the database.
WithAfterUpdatefunc(ctx context.Context, instance any) errorImmediately after an existing record is updated in the database.
WithBeforeSavefunc(ctx context.Context, instance any) errorBefore either create or update execution.
WithAfterSavefunc(ctx context.Context, instance any) errorAfter either create or update execution succeeds.
WithBeforeDeletefunc(ctx context.Context, instance any) errorBefore a record is deleted from the database.
WithAfterDeletefunc(ctx context.Context, instance any) errorAfter a record has been deleted from the database.
WithCleanfunc(instance any) errorInvoked during Validate() or pre-save validation passes.

Execution Lifecycle Order​

On Record Creation (Create / Save on new instance)​

  1. Clean(instance) — Validate cross-field business constraints.
  2. BeforeSave(ctx, instance) — Common pre-save normalization (e.g. slug generation).
  3. BeforeCreate(ctx, instance) — Creation-specific tasks (e.g. assigning UUIDs or hashing passwords).
  4. Database Transaction / SQL INSERT
  5. AfterCreate(ctx, instance) — Fire event, publish audit log.
  6. AfterSave(ctx, instance) — Common post-save notifications.

On Record Update (Update / Save on existing instance)​

  1. Clean(instance) — Validate updated fields.
  2. BeforeSave(ctx, instance) — Re-calculate computed attributes.
  3. BeforeUpdate(ctx, instance) — Check permission or log old vs new diffs.
  4. Database Transaction / SQL UPDATE
  5. AfterUpdate(ctx, instance) — Clear caches.
  6. AfterSave(ctx, instance) — Common post-save triggers.

Practical Example​

func (Order) Hooks() *schema.ModelHooks {
return schema.NewModelHooks().
WithClean(func(instance interface{}) error {
order := instance.(*Order)
if order.ShippingAmount < 0 {
return errors.New("shipping amount cannot be negative")
}
return nil
}).
WithBeforeSave(func(ctx context.Context, instance interface{}) error {
order := instance.(*Order)
// Compute total amount from items, tax, and shipping
order.TotalAmount = order.Subtotal + order.TaxAmount + order.ShippingAmount
return nil
}).
WithAfterCreate(func(ctx context.Context, instance interface{}) error {
order := instance.(*Order)
// Fire asynchronous webhook or email event
go NotifyOrderPlaced(order.ID)
return nil
})
}