mirror of https://github.com/go-gorm/gorm.git
Test Nested Preload
This commit is contained in:
parent
f0a442adff
commit
e60a8d54ff
|
@ -22,7 +22,7 @@ func preload(db *gorm.DB, rels []*schema.Relationship, conds []interface{}) {
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(rels) > 1 {
|
if len(rels) > 1 {
|
||||||
reflectValue = schema.GetRelationsValues(reflectValue, rels[:len(rels)])
|
reflectValue = schema.GetRelationsValues(reflectValue, rels[:len(rels)-1])
|
||||||
}
|
}
|
||||||
|
|
||||||
if rel.JoinTable != nil {
|
if rel.JoinTable != nil {
|
||||||
|
@ -107,9 +107,9 @@ func preload(db *gorm.DB, rels []*schema.Relationship, conds []interface{}) {
|
||||||
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, reflectResults.Index(i).Addr()).Interface())
|
|
||||||
} else {
|
|
||||||
rel.Field.Set(data, reflect.Append(reflectFieldValue, reflectResults.Index(i)).Interface())
|
rel.Field.Set(data, reflect.Append(reflectFieldValue, reflectResults.Index(i)).Interface())
|
||||||
|
} else {
|
||||||
|
rel.Field.Set(data, reflect.Append(reflectFieldValue, reflectResults.Index(i).Elem()).Interface())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ func (schema Schema) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (schema Schema) MakeSlice() reflect.Value {
|
func (schema Schema) MakeSlice() reflect.Value {
|
||||||
slice := reflect.MakeSlice(reflect.SliceOf(schema.ModelType), 0, 0)
|
slice := reflect.MakeSlice(reflect.SliceOf(reflect.PtrTo(schema.ModelType)), 0, 0)
|
||||||
results := reflect.New(slice.Type())
|
results := reflect.New(slice.Type())
|
||||||
results.Elem().Set(slice)
|
results.Elem().Set(slice)
|
||||||
return results
|
return results
|
||||||
|
|
|
@ -55,17 +55,21 @@ func removeSettingFromTag(tag reflect.StructTag, name string) reflect.StructTag
|
||||||
// GetRelationsValues get relations's values from a reflect value
|
// GetRelationsValues get relations's values from a reflect value
|
||||||
func GetRelationsValues(reflectValue reflect.Value, rels []*Relationship) (reflectResults reflect.Value) {
|
func GetRelationsValues(reflectValue reflect.Value, rels []*Relationship) (reflectResults reflect.Value) {
|
||||||
for _, rel := range rels {
|
for _, rel := range rels {
|
||||||
reflectResults = reflect.MakeSlice(reflect.SliceOf(rel.FieldSchema.ModelType), 0, 0)
|
reflectResults = reflect.MakeSlice(reflect.SliceOf(reflect.PtrTo(rel.FieldSchema.ModelType)), 0, 0)
|
||||||
|
|
||||||
appendToResults := func(value reflect.Value) {
|
appendToResults := func(value reflect.Value) {
|
||||||
if _, isZero := rel.Field.ValueOf(value); !isZero {
|
if _, isZero := rel.Field.ValueOf(value); !isZero {
|
||||||
result := reflect.Indirect(rel.Field.ReflectValueOf(value))
|
result := reflect.Indirect(rel.Field.ReflectValueOf(value))
|
||||||
switch result.Kind() {
|
switch result.Kind() {
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
reflectResults = reflect.Append(reflectResults, result)
|
reflectResults = reflect.Append(reflectResults, result.Addr())
|
||||||
case reflect.Slice, reflect.Array:
|
case reflect.Slice, reflect.Array:
|
||||||
for i := 0; i < value.Len(); i++ {
|
for i := 0; i < result.Len(); i++ {
|
||||||
reflectResults = reflect.Append(reflectResults, reflect.Indirect(value.Index(i)))
|
if result.Index(i).Kind() == reflect.Ptr {
|
||||||
|
reflectResults = reflect.Append(reflectResults, result.Index(i))
|
||||||
|
} else {
|
||||||
|
reflectResults = reflect.Append(reflectResults, result.Index(i).Addr())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package tests_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/jinzhu/gorm/tests"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNestedPreload(t *testing.T) {
|
||||||
|
var user = *GetUser("nested_preload", Config{Pets: 2})
|
||||||
|
|
||||||
|
for idx, pet := range user.Pets {
|
||||||
|
pet.Toy = Toy{Name: "toy_nested_preload_" + strconv.Itoa(idx+1)}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DB.Create(&user).Error; err != nil {
|
||||||
|
t.Fatalf("errors happened when create: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var user2 User
|
||||||
|
DB.Preload("Pets.Toy").Find(&user2, "id = ?", user.ID)
|
||||||
|
|
||||||
|
CheckUser(t, user2, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNestedPreloadForSlice(t *testing.T) {
|
||||||
|
var users = []User{
|
||||||
|
*GetUser("slice_nested_preload_1", Config{Pets: 2}),
|
||||||
|
*GetUser("slice_nested_preload_2", Config{Pets: 0}),
|
||||||
|
*GetUser("slice_nested_preload_3", Config{Pets: 3}),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, user := range users {
|
||||||
|
for idx, pet := range user.Pets {
|
||||||
|
pet.Toy = Toy{Name: user.Name + "_toy_nested_preload_" + strconv.Itoa(idx+1)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := DB.Create(&users).Error; err != nil {
|
||||||
|
t.Fatalf("errors happened when create: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var userIDs []uint
|
||||||
|
for _, user := range users {
|
||||||
|
userIDs = append(userIDs, user.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
var users2 []User
|
||||||
|
DB.Preload("Pets.Toy").Find(&users2, "id IN ?", userIDs)
|
||||||
|
|
||||||
|
for idx, user := range users2 {
|
||||||
|
CheckUser(t, user, users[idx])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPreloadWithConds(t *testing.T) {
|
||||||
|
}
|
Loading…
Reference in New Issue