fix: update panic if model is not ptr (#6037)
* fix: update panic if model is not ptr * fix: update panic if model is not ptr * fix: update panic if model is not ptr * fix: raise an error if the value is not addressable * fix: return
This commit is contained in:
		
							parent
							
								
									42fc75cb2c
								
							
						
					
					
						commit
						e66a059b82
					
				| @ -13,11 +13,20 @@ func callMethod(db *gorm.DB, fc func(value interface{}, tx *gorm.DB) bool) { | ||||
| 		case reflect.Slice, reflect.Array: | ||||
| 			db.Statement.CurDestIndex = 0 | ||||
| 			for i := 0; i < db.Statement.ReflectValue.Len(); i++ { | ||||
| 				fc(reflect.Indirect(db.Statement.ReflectValue.Index(i)).Addr().Interface(), tx) | ||||
| 				if value := reflect.Indirect(db.Statement.ReflectValue.Index(i)); value.CanAddr() { | ||||
| 					fc(value.Addr().Interface(), tx) | ||||
| 				} else { | ||||
| 					db.AddError(gorm.ErrInvalidValue) | ||||
| 					return | ||||
| 				} | ||||
| 				db.Statement.CurDestIndex++ | ||||
| 			} | ||||
| 		case reflect.Struct: | ||||
| 			if db.Statement.ReflectValue.CanAddr() { | ||||
| 				fc(db.Statement.ReflectValue.Addr().Interface(), tx) | ||||
| 			} else { | ||||
| 				db.AddError(gorm.ErrInvalidValue) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -137,9 +137,11 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) { | ||||
| 	case reflect.Slice, reflect.Array: | ||||
| 		assignValue = func(field *schema.Field, value interface{}) { | ||||
| 			for i := 0; i < stmt.ReflectValue.Len(); i++ { | ||||
| 				if stmt.ReflectValue.CanAddr() { | ||||
| 					field.Set(stmt.Context, stmt.ReflectValue.Index(i), value) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	case reflect.Struct: | ||||
| 		assignValue = func(field *schema.Field, value interface{}) { | ||||
| 			if stmt.ReflectValue.CanAddr() { | ||||
|  | ||||
| @ -133,7 +133,7 @@ func GetIdentityFieldValuesMap(ctx context.Context, reflectValue reflect.Value, | ||||
| 		for i := 0; i < reflectValue.Len(); i++ { | ||||
| 			elem := reflectValue.Index(i) | ||||
| 			elemKey := elem.Interface() | ||||
| 			if elem.Kind() != reflect.Ptr { | ||||
| 			if elem.Kind() != reflect.Ptr && elem.CanAddr() { | ||||
| 				elemKey = elem.Addr().Interface() | ||||
| 			} | ||||
| 
 | ||||
|  | ||||
| @ -514,3 +514,55 @@ func TestFailedToSaveAssociationShouldRollback(t *testing.T) { | ||||
| 		t.Fatalf("AfterFind should not be called times:%d", productWithItem.Item.AfterFindCallTimes) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| type Product5 struct { | ||||
| 	gorm.Model | ||||
| 	Name string | ||||
| } | ||||
| 
 | ||||
| var beforeUpdateCall int | ||||
| 
 | ||||
| func (p *Product5) BeforeUpdate(*gorm.DB) error { | ||||
| 	beforeUpdateCall = beforeUpdateCall + 1 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func TestUpdateCallbacks(t *testing.T) { | ||||
| 	DB.Migrator().DropTable(&Product5{}) | ||||
| 	DB.AutoMigrate(&Product5{}) | ||||
| 
 | ||||
| 	p := Product5{Name: "unique_code"} | ||||
| 	DB.Model(&Product5{}).Create(&p) | ||||
| 
 | ||||
| 	err := DB.Model(&Product5{}).Where("id", p.ID).Update("name", "update_name_1").Error | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("should update success, but got err %v", err) | ||||
| 	} | ||||
| 	if beforeUpdateCall != 1 { | ||||
| 		t.Fatalf("before update should be called") | ||||
| 	} | ||||
| 
 | ||||
| 	err = DB.Model(Product5{}).Where("id", p.ID).Update("name", "update_name_2").Error | ||||
| 	if !errors.Is(err, gorm.ErrInvalidValue) { | ||||
| 		t.Fatalf("should got RecordNotFound, but got %v", err) | ||||
| 	} | ||||
| 	if beforeUpdateCall != 1 { | ||||
| 		t.Fatalf("before update should not be called") | ||||
| 	} | ||||
| 
 | ||||
| 	err = DB.Model([1]*Product5{&p}).Update("name", "update_name_3").Error | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("should update success, but got err %v", err) | ||||
| 	} | ||||
| 	if beforeUpdateCall != 2 { | ||||
| 		t.Fatalf("before update should be called") | ||||
| 	} | ||||
| 
 | ||||
| 	err = DB.Model([1]Product5{p}).Update("name", "update_name_4").Error | ||||
| 	if !errors.Is(err, gorm.ErrInvalidValue) { | ||||
| 		t.Fatalf("should got RecordNotFound, but got %v", err) | ||||
| 	} | ||||
| 	if beforeUpdateCall != 2 { | ||||
| 		t.Fatalf("before update should not be called") | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 black-06
						black-06