func New(db *gorm.DB) *Publish { tableHandler := gorm.DefaultTableNameHandler gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string { tableName := tableHandler(db, defaultTableName) if db != nil { if IsPublishableModel(db.Value) { // Set join table handler typ := utils.ModelType(db.Value) if !injectedJoinTableHandler[typ] { injectedJoinTableHandler[typ] = true scope := db.NewScope(db.Value) for _, field := range scope.GetModelStruct().StructFields { if many2many := utils.ParseTagOption(field.Tag.Get("gorm"))["MANY2MANY"]; many2many != "" { db.SetJoinTableHandler(db.Value, field.Name, &publishJoinTableHandler{}) db.AutoMigrate(db.Value) } } } var forceDraftTable bool if forceDraftTable, ok := db.Get("publish:force_draft_table"); ok { if forceMode, ok := forceDraftTable.(bool); ok && forceMode { forceDraftTable = true } } if IsDraftMode(db) || forceDraftTable { return DraftTableName(tableName) } } } return tableName } db.AutoMigrate(&PublishEvent{}) db.Callback().Create().Before("gorm:begin_transaction").Register("publish:set_table_to_draft", setTableAndPublishStatus(true)) db.Callback().Create().Before("gorm:commit_or_rollback_transaction"). Register("publish:sync_to_production_after_create", syncCreateFromProductionToDraft) db.Callback().Create().Before("gorm:commit_or_rollback_transaction").Register("gorm:create_publish_event", createPublishEvent) db.Callback().Delete().Before("gorm:begin_transaction").Register("publish:set_table_to_draft", setTableAndPublishStatus(true)) db.Callback().Delete().Replace("gorm:delete", deleteScope) db.Callback().Delete().Before("gorm:commit_or_rollback_transaction"). Register("publish:sync_to_production_after_delete", syncDeleteFromProductionToDraft) db.Callback().Delete().Before("gorm:commit_or_rollback_transaction").Register("gorm:create_publish_event", createPublishEvent) db.Callback().Update().Before("gorm:begin_transaction").Register("publish:set_table_to_draft", setTableAndPublishStatus(true)) db.Callback().Update().Before("gorm:commit_or_rollback_transaction"). Register("publish:sync_to_production", syncUpdateFromProductionToDraft) db.Callback().Update().Before("gorm:commit_or_rollback_transaction").Register("gorm:create_publish_event", createPublishEvent) db.Callback().RowQuery().Register("publish:set_table_in_draft_mode", setTableAndPublishStatus(false)) db.Callback().Query().Before("gorm:query").Register("publish:set_table_in_draft_mode", setTableAndPublishStatus(false)) return &Publish{DB: db} }