Add error explanations when preloading assocations w/o foreign fields, close #4356

This commit is contained in:
Jinzhu 2021-07-13 21:00:13 +08:00
parent b13732c450
commit 52b72d7ef2
1 changed files with 19 additions and 14 deletions

View File

@ -1,6 +1,7 @@
package callbacks package callbacks
import ( import (
"fmt"
"reflect" "reflect"
"gorm.io/gorm" "gorm.io/gorm"
@ -144,23 +145,27 @@ func preload(db *gorm.DB, rel *schema.Relationship, conds []interface{}, preload
fieldValues[idx], _ = field.ValueOf(elem) fieldValues[idx], _ = field.ValueOf(elem)
} }
for _, data := range identityMap[utils.ToStringKey(fieldValues...)] { if datas, ok := identityMap[utils.ToStringKey(fieldValues...)]; ok {
reflectFieldValue := rel.Field.ReflectValueOf(data) for _, data := range datas {
if reflectFieldValue.Kind() == reflect.Ptr && reflectFieldValue.IsNil() { reflectFieldValue := rel.Field.ReflectValueOf(data)
reflectFieldValue.Set(reflect.New(rel.Field.FieldType.Elem())) if reflectFieldValue.Kind() == reflect.Ptr && reflectFieldValue.IsNil() {
} reflectFieldValue.Set(reflect.New(rel.Field.FieldType.Elem()))
}
reflectFieldValue = reflect.Indirect(reflectFieldValue) reflectFieldValue = reflect.Indirect(reflectFieldValue)
switch reflectFieldValue.Kind() { switch reflectFieldValue.Kind() {
case reflect.Struct: case reflect.Struct:
rel.Field.Set(data, reflectResults.Index(i).Interface()) rel.Field.Set(data, reflectResults.Index(i).Interface())
case reflect.Slice, reflect.Array: case reflect.Slice, reflect.Array:
if reflectFieldValue.Type().Elem().Kind() == reflect.Ptr { if reflectFieldValue.Type().Elem().Kind() == reflect.Ptr {
rel.Field.Set(data, reflect.Append(reflectFieldValue, elem).Interface()) rel.Field.Set(data, reflect.Append(reflectFieldValue, elem).Interface())
} else { } else {
rel.Field.Set(data, reflect.Append(reflectFieldValue, elem.Elem()).Interface()) rel.Field.Set(data, reflect.Append(reflectFieldValue, elem.Elem()).Interface())
}
} }
} }
} else {
db.AddError(fmt.Errorf("failed to assign association %#v, make sure foreign fields exists", elem.Interface()))
} }
} }
} }