Callbacks

GORM itself is powered by Callbacks, it has callbacks for Create, Query, Update, Delete, Row, Raw, you could fully customize GORM with them as you want

Callbacks are registered into the global *gorm.DB, not the session-level, if you require *gorm.DB with different callbacks, you need to initialize another *gorm.DB

Register Callback

Register a callback into callbacks

  1. func cropImage(db *gorm.DB) {
  2. if db.Statement.Schema != nil {
  3. // crop image fields and upload them to CDN, dummy code
  4. for _, field := range db.Statement.Schema.Fields {
  5. switch db.Statement.ReflectValue.Kind() {
  6. case reflect.Slice, reflect.Array:
  7. for i := 0; i < db.Statement.ReflectValue.Len(); i++ {
  8. // Get value from field
  9. if fieldValue, isZero := field.ValueOf(db.Statement.Context, db.Statement.ReflectValue.Index(i)); !isZero {
  10. if crop, ok := fieldValue.(CropInterface); ok {
  11. crop.Crop()
  12. }
  13. }
  14. }
  15. case reflect.Struct:
  16. // Get value from field
  17. if fieldValue, isZero := field.ValueOf(db.Statement.Context, db.Statement.ReflectValue); !isZero {
  18. if crop, ok := fieldValue.(CropInterface); ok {
  19. crop.Crop()
  20. }
  21. }
  22. // Set value to field
  23. err := field.Set(db.Statement.Context, db.Statement.ReflectValue, "newValue")
  24. }
  25. }
  26. // All fields for current model
  27. db.Statement.Schema.Fields
  28. // All primary key fields for current model
  29. db.Statement.Schema.PrimaryFields
  30. // Prioritized primary key field: field with DB name `id` or the first defined primary key
  31. db.Statement.Schema.PrioritizedPrimaryField
  32. // All relationships for current model
  33. db.Statement.Schema.Relationships
  34. // Find field with field name or db name
  35. field := db.Statement.Schema.LookUpField("Name")
  36. // processing
  37. }
  38. }
  39. db.Callback().Create().Register("crop_image", cropImage)
  40. // register a callback for Create process

Delete Callback

Delete a callback from callbacks

  1. db.Callback().Create().Remove("gorm:create")
  2. // delete callback `gorm:create` from Create callbacks

Replace Callback

Replace a callback having the same name with the new one

  1. db.Callback().Create().Replace("gorm:create", newCreateFunction)
  2. // replace callback `gorm:create` with new function `newCreateFunction` for Create process

Register Callback with orders

Register callbacks with orders

  1. // before gorm:create
  2. db.Callback().Create().Before("gorm:create").Register("update_created_at", updateCreated)
  3. // after gorm:create
  4. db.Callback().Create().After("gorm:create").Register("update_created_at", updateCreated)
  5. // after gorm:query
  6. db.Callback().Query().After("gorm:query").Register("my_plugin:after_query", afterQuery)
  7. // after gorm:delete
  8. db.Callback().Delete().After("gorm:delete").Register("my_plugin:after_delete", afterDelete)
  9. // before gorm:update
  10. db.Callback().Update().Before("gorm:update").Register("my_plugin:before_update", beforeUpdate)
  11. // before gorm:create and after gorm:before_create
  12. db.Callback().Create().Before("gorm:create").After("gorm:before_create").Register("my_plugin:before_create", beforeCreate)
  13. // before any other callbacks
  14. db.Callback().Create().Before("*").Register("update_created_at", updateCreated)
  15. // after any other callbacks
  16. db.Callback().Create().After("*").Register("update_created_at", updateCreated)

Defined Callbacks

GORM has defined some callbacks to power current GORM features, check them out before starting your plugins

Plugin

GORM provides a Use method to register plugins, the plugin needs to implement the Plugin interface

  1. type Plugin interface {
  2. Name() string
  3. Initialize(*gorm.DB) error
  4. }

The Initialize method will be invoked when registering the plugin into GORM first time, and GORM will save the registered plugins, access them like:

  1. db.Config.Plugins[pluginName]

Checkout Prometheus as example