Fixed nil error when first updates with struct

This commit is contained in:
Emir Beganovic 2019-05-05 13:12:03 +04:00
parent 206174c932
commit 394b3a1818
2 changed files with 26 additions and 5 deletions

View File

@ -1182,6 +1182,27 @@ func TestFloatColumnPrecision(t *testing.T) {
} }
} }
func TestWhereUpdates(t *testing.T) {
type OwnerEntity struct {
gorm.Model
OwnerID uint
OwnerType string
}
type SomeEntity struct {
gorm.Model
Name string
OwnerEntity OwnerEntity `gorm:"polymorphic:Owner"`
}
db := DB.Debug()
db.DropTable(&SomeEntity{})
db.AutoMigrate(&SomeEntity{})
a := SomeEntity{Name: "test"}
db.Model(&a).Where(a).Updates(SomeEntity{Name: "test2"})
}
func BenchmarkGorm(b *testing.B) { func BenchmarkGorm(b *testing.B) {
b.N = 2000 b.N = 2000
for x := 0; x < b.N; x++ { for x := 0; x < b.N; x++ {

View File

@ -872,7 +872,7 @@ func (scope *Scope) callCallbacks(funcs []*func(s *Scope)) *Scope {
return scope return scope
} }
func convertInterfaceToMap(values interface{}, withIgnoredField bool) map[string]interface{} { func convertInterfaceToMap(values interface{}, withIgnoredField bool, db *DB) map[string]interface{} {
var attrs = map[string]interface{}{} var attrs = map[string]interface{}{}
switch value := values.(type) { switch value := values.(type) {
@ -880,7 +880,7 @@ func convertInterfaceToMap(values interface{}, withIgnoredField bool) map[string
return value return value
case []interface{}: case []interface{}:
for _, v := range value { for _, v := range value {
for key, value := range convertInterfaceToMap(v, withIgnoredField) { for key, value := range convertInterfaceToMap(v, withIgnoredField, db) {
attrs[key] = value attrs[key] = value
} }
} }
@ -893,7 +893,7 @@ func convertInterfaceToMap(values interface{}, withIgnoredField bool) map[string
attrs[ToColumnName(key.Interface().(string))] = reflectValue.MapIndex(key).Interface() attrs[ToColumnName(key.Interface().(string))] = reflectValue.MapIndex(key).Interface()
} }
default: default:
for _, field := range (&Scope{Value: values}).Fields() { for _, field := range (&Scope{Value: values, db: db}).Fields() {
if !field.IsBlank && (withIgnoredField || !field.IsIgnored) { if !field.IsBlank && (withIgnoredField || !field.IsIgnored) {
attrs[field.DBName] = field.Field.Interface() attrs[field.DBName] = field.Field.Interface()
} }
@ -905,12 +905,12 @@ func convertInterfaceToMap(values interface{}, withIgnoredField bool) map[string
func (scope *Scope) updatedAttrsWithValues(value interface{}) (results map[string]interface{}, hasUpdate bool) { func (scope *Scope) updatedAttrsWithValues(value interface{}) (results map[string]interface{}, hasUpdate bool) {
if scope.IndirectValue().Kind() != reflect.Struct { if scope.IndirectValue().Kind() != reflect.Struct {
return convertInterfaceToMap(value, false), true return convertInterfaceToMap(value, false, scope.db), true
} }
results = map[string]interface{}{} results = map[string]interface{}{}
for key, value := range convertInterfaceToMap(value, true) { for key, value := range convertInterfaceToMap(value, true, scope.db) {
if field, ok := scope.FieldByName(key); ok && scope.changeableField(field) { if field, ok := scope.FieldByName(key); ok && scope.changeableField(field) {
if _, ok := value.(*expr); ok { if _, ok := value.(*expr); ok {
hasUpdate = true hasUpdate = true