Fix V2 Save compatibility, close #3332
This commit is contained in:
		
							parent
							
								
									59586dcd31
								
							
						
					
					
						commit
						b4166d9515
					
				| @ -417,7 +417,7 @@ func (association *Association) saveAssociation(clear bool, values ...interface{ | ||||
| 			appendToRelations(reflectValue.Index(i), reflect.Indirect(reflect.ValueOf(values[i])), clear) | ||||
| 
 | ||||
| 			// TODO support save slice data, sql with case?
 | ||||
| 			association.Error = association.DB.Session(&Session{}).Select(selectedSaveColumns).Model(nil).Save(reflectValue.Index(i).Addr().Interface()).Error | ||||
| 			association.Error = association.DB.Session(&Session{}).Select(selectedSaveColumns).Model(nil).Updates(reflectValue.Index(i).Addr().Interface()).Error | ||||
| 		} | ||||
| 	case reflect.Struct: | ||||
| 		// clear old data
 | ||||
| @ -439,7 +439,7 @@ func (association *Association) saveAssociation(clear bool, values ...interface{ | ||||
| 		} | ||||
| 
 | ||||
| 		if len(values) > 0 { | ||||
| 			association.Error = association.DB.Session(&Session{}).Select(selectedSaveColumns).Model(nil).Save(reflectValue.Addr().Interface()).Error | ||||
| 			association.Error = association.DB.Session(&Session{}).Select(selectedSaveColumns).Model(nil).Updates(reflectValue.Addr().Interface()).Error | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -319,7 +319,7 @@ func ConvertToCreateValues(stmt *gorm.Statement) (values clause.Values) { | ||||
| 	} | ||||
| 
 | ||||
| 	if stmt.UpdatingColumn { | ||||
| 		if stmt.Schema != nil { | ||||
| 		if stmt.Schema != nil && len(values.Columns) > 1 { | ||||
| 			columns := make([]string, 0, len(values.Columns)-1) | ||||
| 			for _, column := range values.Columns { | ||||
| 				if field := stmt.Schema.LookUpField(column.Name); field != nil { | ||||
|  | ||||
| @ -42,11 +42,19 @@ func (db *DB) Save(value interface{}) (tx *DB) { | ||||
| 
 | ||||
| 		fallthrough | ||||
| 	default: | ||||
| 		if len(tx.Statement.Selects) == 0 { | ||||
| 		selectedUpdate := len(tx.Statement.Selects) != 0 | ||||
| 		// when updating, use all fields including those zero-value fields
 | ||||
| 		if !selectedUpdate { | ||||
| 			tx.Statement.Selects = append(tx.Statement.Selects, "*") | ||||
| 		} | ||||
| 
 | ||||
| 		tx.callbacks.Update().Execute(tx) | ||||
| 
 | ||||
| 		if tx.Error == nil && tx.RowsAffected == 0 && !tx.DryRun && !selectedUpdate { | ||||
| 			if err := tx.Session(&Session{}).First(value).Error; errors.Is(err, ErrRecordNotFound) { | ||||
| 				return tx.Create(value) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return | ||||
|  | ||||
| @ -9,7 +9,7 @@ require ( | ||||
| 	gorm.io/driver/mysql v1.0.0 | ||||
| 	gorm.io/driver/postgres v1.0.0 | ||||
| 	gorm.io/driver/sqlite v1.1.0 | ||||
| 	gorm.io/driver/sqlserver v1.0.0 | ||||
| 	gorm.io/driver/sqlserver v1.0.1 | ||||
| 	gorm.io/gorm v1.9.19 | ||||
| ) | ||||
| 
 | ||||
|  | ||||
| @ -610,3 +610,23 @@ func TestSave(t *testing.T) { | ||||
| 		t.Fatalf("invalid updating SQL, got %v", stmt.SQL.String()) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestSaveWithPrimaryValue(t *testing.T) { | ||||
| 	lang := Language{Code: "save", Name: "save"} | ||||
| 	if result := DB.Save(&lang); result.RowsAffected != 1 { | ||||
| 		t.Errorf("should create language, rows affected: %v", result.RowsAffected) | ||||
| 	} | ||||
| 
 | ||||
| 	var result Language | ||||
| 	DB.First(&result, "code = ?", "save") | ||||
| 	AssertEqual(t, result, lang) | ||||
| 
 | ||||
| 	lang.Name = "save name2" | ||||
| 	if result := DB.Save(&lang); result.RowsAffected != 1 { | ||||
| 		t.Errorf("should update language") | ||||
| 	} | ||||
| 
 | ||||
| 	var result2 Language | ||||
| 	DB.First(&result2, "code = ?", "save") | ||||
| 	AssertEqual(t, result2, lang) | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinzhu
						Jinzhu