From d02c2a37ea645f700d0d470f65a2746135d6e141 Mon Sep 17 00:00:00 2001 From: Dirk-Jan Date: Mon, 9 May 2016 14:15:35 +0200 Subject: [PATCH] Improved preload m2m performance --- callback_query_preload.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/callback_query_preload.go b/callback_query_preload.go index 5746f533..d95eae07 100644 --- a/callback_query_preload.go +++ b/callback_query_preload.go @@ -153,16 +153,24 @@ func (scope *Scope) handleHasManyPreload(field *Field, conditions []interface{}) ) if indirectScopeValue.Kind() == reflect.Slice { + preloadMap := make(map[string][]reflect.Value) for i := 0; i < resultsValue.Len(); i++ { result := resultsValue.Index(i) foreignValues := getValueFromFields(result, relation.ForeignFieldNames) - for j := 0; j < indirectScopeValue.Len(); j++ { - object := indirect(indirectScopeValue.Index(j)) - if equalAsString(getValueFromFields(object, relation.AssociationForeignFieldNames), foreignValues) { - objectField := object.FieldByName(field.Name) - objectField.Set(reflect.Append(objectField, result)) - break + preloadMap[toString(foreignValues)] = append(preloadMap[toString(foreignValues)], result) + } + + objects := scope.IndirectValue() + for j := 0; j < objects.Len(); j++ { + object := reflect.Indirect(objects.Index(j)) + objectRealValue := getValueFromFields(object, relation.AssociationForeignFieldNames) + objectStringValue := toString(objectRealValue) + if results, ok := preloadMap[objectStringValue]; ok { + if object.Kind() == reflect.Ptr { + object = object.Elem() } + f := object.FieldByName(field.Name) + f.Set(reflect.Append(f, results...)) } } } else {