// Package models provides GORM models and business logic. // Audited models inspired by https://github.com/qor/audited package models import ( "gorm.io/gorm" ) // AuditedCurrentUserKey is the GORM Set key for the current user. const AuditedCurrentUserKey = "audited:current_user" // Audited tracks creator and updater IDs. type Audited struct { CreatorID *int64 `gorm:"type:bigint REFERENCES users(id)" json:"-"` Creator *User `json:"-"` UpdaterID *int64 `gorm:"type:bigint REFERENCES users(id)" json:"-"` Updater *User `json:"-"` } func getCurrentUser(scope *gorm.DB) (int64, bool) { var user interface{} var hasUser bool user, hasUser = scope.Get(AuditedCurrentUserKey) // spew.Dump(user, hasUser) if hasUser { return user.(*User).ID, true } return 0, false } func assignCreatedBy(tx *gorm.DB) { name := "CreatorID" if field := tx.Statement.Schema.LookUpField(name); field != nil { if user, ok := getCurrentUser(tx); ok { tx.Statement.SetColumn(name, user) } } } func assignUpdatedBy(tx *gorm.DB) { name := "UpdaterID" if field := tx.Statement.Schema.LookUpField(name); field != nil { if user, ok := getCurrentUser(tx); ok { tx.Statement.SetColumn("UpdaterID", user, true) } } } // RegisterCallbacks register callback into GORM DB func RegisterCallbacks(db *gorm.DB) { callback := db.Callback() if callback.Create().Get("audited:assign_created_by") == nil { _ = callback.Create().After("gorm:before_create").Register("audited:assign_created_by", assignCreatedBy) } if callback.Update().Get("audited:assign_updated_by") == nil { _ = callback.Update().After("gorm:before_update").Register("audited:assign_updated_by", assignUpdatedBy) } }