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.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.ReflectValue); !isZero {
18. if crop, ok := fieldValue.(CropInterface); ok {
19. crop.Crop()
20. }
21. }

23. // Set value to field
24. err := field.Set(db.Statement.ReflectValue, "newValue")
25. }
26. }

28. // All fields for current model
29. db.Statement.Schema.Fields

31. // All primary key fields for current model
32. db.Statement.Schema.PrimaryFields

34. // Prioritized primary key field: field with DB name `id` or the first defined primary key
35. db.Statement.Schema.PrioritizedPrimaryField

37. // All relationships for current model
38. db.Statement.Schema.Relationships

40. // Find field with field name or db name
41. field := db.Statement.Schema.LookUpField("Name")

43. // processing
44. }
45. }

47. db.Callback().Create().Register("crop_image", cropImage)
48. // 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)

4. // after gorm:create
5. db.Callback().Create().After("gorm:create").Register("update_created_at", updateCreated)

7. // after gorm:query
8. db.Callback().Query().After("gorm:query").Register("my_plugin:after_query", afterQuery)

10. // after gorm:delete
11. db.Callback().Delete().After("gorm:delete").Register("my_plugin:after_delete", afterDelete)

13. // before gorm:update
14. db.Callback().Update().Before("gorm:update").Register("my_plugin:before_update", beforeUpdate)

16. // before gorm:create and after gorm:before_create
17. db.Callback().Create().Before("gorm:create").After("gorm:before_create").Register("my_plugin:before_create", beforeCreate)

19. // before any other callbacks
20. db.Callback().Create().Before("*").Register("update_created_at", updateCreated)

22. // after any other callbacks
23. 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