Fix preload duplicates has many related objects

This commit is contained in:
Jinzhu 2016-07-10 21:34:37 +08:00
parent 24501a3c1a
commit ca46038cb4
3 changed files with 10 additions and 10 deletions

View File

@ -186,13 +186,6 @@ func (scope *Scope) handleHasManyPreload(field *Field, conditions []interface{})
for j := 0; j < indirectScopeValue.Len(); j++ { for j := 0; j < indirectScopeValue.Len(); j++ {
object := indirect(indirectScopeValue.Index(j)) object := indirect(indirectScopeValue.Index(j))
objectRealValue := getValueFromFields(object, relation.AssociationForeignFieldNames) objectRealValue := getValueFromFields(object, relation.AssociationForeignFieldNames)
if j > 0 {
prevObject := indirect(indirectScopeValue.Index(j - 1))
prevObjectRealValue := getValueFromFields(prevObject, relation.AssociationForeignFieldNames)
if toString(prevObjectRealValue) == toString(objectRealValue) {
continue
}
}
if results, ok := preloadMap[toString(objectRealValue)]; ok { if results, ok := preloadMap[toString(objectRealValue)]; ok {
f := object.FieldByName(field.Name) f := object.FieldByName(field.Name)
f.Set(reflect.Append(f, results...)) f.Set(reflect.Append(f, results...))

View File

@ -1513,19 +1513,23 @@ func TestPrefixedPreloadDuplication(t *testing.T) {
type ( type (
Level4 struct { Level4 struct {
ID uint ID uint
Name string
Level3ID uint Level3ID uint
} }
Level3 struct { Level3 struct {
ID uint ID uint
Name string
Level4s []*Level4 Level4s []*Level4
} }
Level2 struct { Level2 struct {
ID uint ID uint
Name string
Level3ID sql.NullInt64 `sql:"index"` Level3ID sql.NullInt64 `sql:"index"`
Level3 *Level3 Level3 *Level3
} }
Level1 struct { Level1 struct {
ID uint ID uint
Name string
Level2ID sql.NullInt64 `sql:"index"` Level2ID sql.NullInt64 `sql:"index"`
Level2 *Level2 Level2 *Level2
} }
@ -1540,7 +1544,7 @@ func TestPrefixedPreloadDuplication(t *testing.T) {
t.Error(err) t.Error(err)
} }
lvl := new(Level3) lvl := &Level3{}
if err := DB.Save(lvl).Error; err != nil { if err := DB.Save(lvl).Error; err != nil {
t.Error(err) t.Error(err)
} }

View File

@ -1237,6 +1237,7 @@ func (scope *Scope) getColumnAsScope(column string) *Scope {
fieldType = fieldType.Elem() fieldType = fieldType.Elem()
} }
resultsMap := map[interface{}]bool{}
results := reflect.New(reflect.SliceOf(reflect.PtrTo(fieldType))).Elem() results := reflect.New(reflect.SliceOf(reflect.PtrTo(fieldType))).Elem()
for i := 0; i < indirectScopeValue.Len(); i++ { for i := 0; i < indirectScopeValue.Len(); i++ {
@ -1244,11 +1245,13 @@ func (scope *Scope) getColumnAsScope(column string) *Scope {
if result.Kind() == reflect.Slice { if result.Kind() == reflect.Slice {
for j := 0; j < result.Len(); j++ { for j := 0; j < result.Len(); j++ {
if elem := result.Index(j); elem.CanAddr() { if elem := result.Index(j); elem.CanAddr() && resultsMap[elem.Addr()] != true {
resultsMap[elem.Addr()] = true
results = reflect.Append(results, elem.Addr()) results = reflect.Append(results, elem.Addr())
} }
} }
} else if result.CanAddr() { } else if result.CanAddr() && resultsMap[result.Addr()] != true {
resultsMap[result.Addr()] = true
results = reflect.Append(results, result.Addr()) results = reflect.Append(results, result.Addr())
} }
} }