feat: copy dest fields to model struct
This commit is contained in:
		
							parent
							
								
									4581e8b590
								
							
						
					
					
						commit
						eaa63d15e7
					
				| @ -23,11 +23,38 @@ func SetupUpdateReflectValue(db *gorm.DB) { | |||||||
| 						rel.Field.Set(db.Statement.ReflectValue, dest[rel.Name]) | 						rel.Field.Set(db.Statement.ReflectValue, dest[rel.Name]) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 			} else if modelType, destType := findType(db.Statement.Model), findType(db.Statement.Dest); modelType.Kind() == reflect.Struct && destType.Kind() == reflect.Struct { | ||||||
|  | 				db.Statement.Dest = transToModel(reflect.Indirect(reflect.ValueOf(db.Statement.Dest)), reflect.New(modelType).Elem()) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func findType(target interface{}) reflect.Type { | ||||||
|  | 	t := reflect.TypeOf(target) | ||||||
|  | 	if t.Kind() == reflect.Ptr { | ||||||
|  | 		return t.Elem() | ||||||
|  | 	} | ||||||
|  | 	return t | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func transToModel(from, to reflect.Value) interface{} { | ||||||
|  | 	if from.String() == to.String() { | ||||||
|  | 		return from.Interface() | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fromType := from.Type() | ||||||
|  | 	for i := 0; i < fromType.NumField(); i++ { | ||||||
|  | 		fieldName := fromType.Field(i).Name | ||||||
|  | 		fromField, toField := from.FieldByName(fieldName), to.FieldByName(fieldName) | ||||||
|  | 		if !toField.IsValid() || !toField.CanSet() || toField.Kind() != fromField.Kind() { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		toField.Set(fromField) | ||||||
|  | 	} | ||||||
|  | 	return to.Interface() | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func BeforeUpdate(db *gorm.DB) { | func BeforeUpdate(db *gorm.DB) { | ||||||
| 	if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && (db.Statement.Schema.BeforeSave || db.Statement.Schema.BeforeUpdate) { | 	if db.Error == nil && db.Statement.Schema != nil && !db.Statement.SkipHooks && (db.Statement.Schema.BeforeSave || db.Statement.Schema.BeforeUpdate) { | ||||||
| 		callMethod(db, func(value interface{}, tx *gorm.DB) (called bool) { | 		callMethod(db, func(value interface{}, tx *gorm.DB) (called bool) { | ||||||
| @ -227,7 +254,7 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) { | |||||||
| 			set = make([]clause.Assignment, 0, len(stmt.Schema.FieldsByDBName)) | 			set = make([]clause.Assignment, 0, len(stmt.Schema.FieldsByDBName)) | ||||||
| 			for _, dbName := range stmt.Schema.DBNames { | 			for _, dbName := range stmt.Schema.DBNames { | ||||||
| 				field := stmt.Schema.LookUpField(dbName) | 				field := stmt.Schema.LookUpField(dbName) | ||||||
| 				if !field.PrimaryKey || (!updatingValue.CanAddr() || stmt.Dest != stmt.Model) { | 				if !field.PrimaryKey || !updatingValue.CanAddr() || stmt.Dest != stmt.Model { | ||||||
| 					if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && (!restricted || (!stmt.SkipHooks && field.AutoUpdateTime > 0))) { | 					if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && (!restricted || (!stmt.SkipHooks && field.AutoUpdateTime > 0))) { | ||||||
| 						value, isZero := field.ValueOf(updatingValue) | 						value, isZero := field.ValueOf(updatingValue) | ||||||
| 						if !stmt.SkipHooks && field.AutoUpdateTime > 0 { | 						if !stmt.SkipHooks && field.AutoUpdateTime > 0 { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 riverchu
						riverchu