Merge pull request #1038 from RichardKnop/bugfix/preload-panic

Fixed an occurrence of a panic while preloading non existent fields.
This commit is contained in:
Jinzhu 2016-06-01 23:10:28 +08:00
commit dca5e54f8b
2 changed files with 65 additions and 7 deletions

View File

@ -28,6 +28,10 @@ func preloadCallback(scope *Scope) {
for idx, preloadField := range preloadFields { for idx, preloadField := range preloadFields {
var currentPreloadConditions []interface{} var currentPreloadConditions []interface{}
if currentScope == nil {
continue
}
// if not preloaded // if not preloaded
if preloadKey := strings.Join(preloadFields[:idx+1], "."); !preloadedMap[preloadKey] { if preloadKey := strings.Join(preloadFields[:idx+1], "."); !preloadedMap[preloadKey] {
@ -67,7 +71,9 @@ func preloadCallback(scope *Scope) {
// preload next level // preload next level
if idx < len(preloadFields)-1 { if idx < len(preloadFields)-1 {
currentScope = currentScope.getColumnAsScope(preloadField) currentScope = currentScope.getColumnAsScope(preloadField)
currentFields = currentScope.Fields() if currentScope != nil {
currentFields = currentScope.Fields()
}
} }
} }
} }

View File

@ -1288,17 +1288,23 @@ func TestNilPointerSlice(t *testing.T) {
t.Error(err) t.Error(err)
} }
want := Level1{Value: "Bob", Level2: &Level2{ want := Level1{
Value: "en", Value: "Bob",
Level3: &Level3{ Level2: &Level2{
Value: "native", Value: "en",
Level3: &Level3{
Value: "native",
},
}, },
}} }
if err := DB.Save(&want).Error; err != nil { if err := DB.Save(&want).Error; err != nil {
t.Error(err) t.Error(err)
} }
want2 := Level1{Value: "Tom", Level2: nil} want2 := Level1{
Value: "Tom",
Level2: nil,
}
if err := DB.Save(&want2).Error; err != nil { if err := DB.Save(&want2).Error; err != nil {
t.Error(err) t.Error(err)
} }
@ -1321,6 +1327,52 @@ func TestNilPointerSlice(t *testing.T) {
} }
} }
func TestNilPointerSlice2(t *testing.T) {
type (
Level4 struct {
ID uint
}
Level3 struct {
ID uint
Level4ID sql.NullInt64 `sql:"index"`
Level4 *Level4
}
Level2 struct {
ID uint
Level3s []*Level3 `gorm:"many2many:level2_level3s"`
}
Level1 struct {
ID uint
Level2ID sql.NullInt64 `sql:"index"`
Level2 *Level2
}
)
DB.DropTableIfExists(new(Level4))
DB.DropTableIfExists(new(Level3))
DB.DropTableIfExists(new(Level2))
DB.DropTableIfExists(new(Level1))
if err := DB.AutoMigrate(new(Level4), new(Level3), new(Level2), new(Level1)).Error; err != nil {
t.Error(err)
}
want := new(Level1)
if err := DB.Save(want).Error; err != nil {
t.Error(err)
}
got := new(Level1)
err := DB.Preload("Level2.Level3s.Level4").Last(&got).Error
if err != nil {
t.Error(err)
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %s; want %s", toJSONString(got), toJSONString(want))
}
}
func toJSONString(v interface{}) []byte { func toJSONString(v interface{}) []byte {
r, _ := json.MarshalIndent(v, "", " ") r, _ := json.MarshalIndent(v, "", " ")
return r return r