Fix preload error when result is empty

This commit is contained in:
Jinzhu 2015-03-02 10:52:18 +08:00
parent b391029188
commit b3d6025365
1 changed files with 52 additions and 46 deletions

View File

@ -34,62 +34,68 @@ func Preload(scope *Scope) {
switch relation.Kind { switch relation.Kind {
case "has_one": case "has_one":
condition := fmt.Sprintf("%v IN (?)", scope.Quote(relation.ForeignDBName)) if primaryKeys := scope.getColumnAsArray(primaryName); len(primaryKeys) > 0 {
scope.NewDB().Where(condition, scope.getColumnAsArray(primaryName)).Find(results, conditions...) condition := fmt.Sprintf("%v IN (?)", scope.Quote(relation.ForeignDBName))
scope.NewDB().Where(condition, primaryKeys).Find(results, conditions...)
resultValues := reflect.Indirect(reflect.ValueOf(results)) resultValues := reflect.Indirect(reflect.ValueOf(results))
for i := 0; i < resultValues.Len(); i++ { for i := 0; i < resultValues.Len(); i++ {
result := resultValues.Index(i) result := resultValues.Index(i)
if isSlice { if isSlice {
value := getRealValue(result, relation.ForeignFieldName) value := getRealValue(result, relation.ForeignFieldName)
objects := scope.IndirectValue() objects := scope.IndirectValue()
for j := 0; j < objects.Len(); j++ { for j := 0; j < objects.Len(); j++ {
if equalAsString(getRealValue(objects.Index(j), primaryName), value) { if equalAsString(getRealValue(objects.Index(j), primaryName), value) {
reflect.Indirect(objects.Index(j)).FieldByName(field.Name).Set(result) reflect.Indirect(objects.Index(j)).FieldByName(field.Name).Set(result)
break break
}
} }
} else {
scope.SetColumn(field, result)
} }
} else {
scope.SetColumn(field, result)
} }
} }
case "has_many": case "has_many":
condition := fmt.Sprintf("%v IN (?)", scope.Quote(relation.ForeignDBName)) if primaryKeys := scope.getColumnAsArray(primaryName); len(primaryKeys) > 0 {
scope.NewDB().Where(condition, scope.getColumnAsArray(primaryName)).Find(results, conditions...) condition := fmt.Sprintf("%v IN (?)", scope.Quote(relation.ForeignDBName))
resultValues := reflect.Indirect(reflect.ValueOf(results)) scope.NewDB().Where(condition, primaryKeys).Find(results, conditions...)
if isSlice { resultValues := reflect.Indirect(reflect.ValueOf(results))
for i := 0; i < resultValues.Len(); i++ {
result := resultValues.Index(i)
value := getRealValue(result, relation.ForeignFieldName)
objects := scope.IndirectValue()
for j := 0; j < objects.Len(); j++ {
object := reflect.Indirect(objects.Index(j))
if equalAsString(getRealValue(object, primaryName), value) {
f := object.FieldByName(field.Name)
f.Set(reflect.Append(f, result))
break
}
}
}
} else {
scope.SetColumn(field, resultValues)
}
case "belongs_to":
scope.NewDB().Where(scope.getColumnAsArray(relation.ForeignFieldName)).Find(results, conditions...)
resultValues := reflect.Indirect(reflect.ValueOf(results))
for i := 0; i < resultValues.Len(); i++ {
result := resultValues.Index(i)
if isSlice { if isSlice {
value := getRealValue(result, associationPrimaryKey) for i := 0; i < resultValues.Len(); i++ {
objects := scope.IndirectValue() result := resultValues.Index(i)
for j := 0; j < objects.Len(); j++ { value := getRealValue(result, relation.ForeignFieldName)
object := reflect.Indirect(objects.Index(j)) objects := scope.IndirectValue()
if equalAsString(getRealValue(object, relation.ForeignFieldName), value) { for j := 0; j < objects.Len(); j++ {
object.FieldByName(field.Name).Set(result) object := reflect.Indirect(objects.Index(j))
if equalAsString(getRealValue(object, primaryName), value) {
f := object.FieldByName(field.Name)
f.Set(reflect.Append(f, result))
break
}
} }
} }
} else { } else {
scope.SetColumn(field, result) scope.SetColumn(field, resultValues)
}
}
case "belongs_to":
if primaryKeys := scope.getColumnAsArray(relation.ForeignFieldName); len(primaryKeys) > 0 {
scope.NewDB().Where(primaryKeys).Find(results, conditions...)
resultValues := reflect.Indirect(reflect.ValueOf(results))
for i := 0; i < resultValues.Len(); i++ {
result := resultValues.Index(i)
if isSlice {
value := getRealValue(result, associationPrimaryKey)
objects := scope.IndirectValue()
for j := 0; j < objects.Len(); j++ {
object := reflect.Indirect(objects.Index(j))
if equalAsString(getRealValue(object, relation.ForeignFieldName), value) {
object.FieldByName(field.Name).Set(result)
}
}
} else {
scope.SetColumn(field, result)
}
} }
} }
case "many_to_many": case "many_to_many":