Fix V2 Save compatibility, close #3332

This commit is contained in:
Jinzhu 2020-08-30 10:12:49 +08:00
parent 59586dcd31
commit b4166d9515
5 changed files with 33 additions and 5 deletions

View File

@ -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
}
}

View File

@ -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 {

View File

@ -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

View File

@ -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
)

View File

@ -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)
}