forked from mirror/gorm
Return empty slice for associations with 0 results
When using `Preload` to include the results of a "has many" relationship, Gorm previously returned an uninitialized slice for any such relations that bore zero records. This distinction was most apparent when the results were marshalled to a JSON representation--a record with zero related records would be represented with `null`. For example, consider the following schema: id | name ---|------ 1 | Lorin 2 | Sue id | p_id | value ---|------|------------------- 1 | 1 | lorin@example.com 2 | 1 | lorin2@example.com Querying with: db.Preload("Email").Find(&people) And marshalling the resulting value of `people` to JSON would yield the following string: [ { "name": "Lorin", "email": [ "lorin@example.com", "lorin2@example.com" ] }, { "name": "Sue", "email": null } ] Beyond being inconsistent, the value `null` in this response differs semantically from the actual state of the database. The database actually has zero related records for the second user, so a JSON value of `[]` is appropriate. Update the callback that processes "has many" relationships to communicate empty query results with an empty slice.
This commit is contained in:
parent
5ec2f6ceb6
commit
f06d6412de
|
@ -186,9 +186,11 @@ func (scope *Scope) handleHasManyPreload(field *Field, conditions []interface{})
|
|||
for j := 0; j < indirectScopeValue.Len(); j++ {
|
||||
object := indirect(indirectScopeValue.Index(j))
|
||||
objectRealValue := getValueFromFields(object, relation.AssociationForeignFieldNames)
|
||||
f := object.FieldByName(field.Name)
|
||||
if results, ok := preloadMap[toString(objectRealValue)]; ok {
|
||||
f := object.FieldByName(field.Name)
|
||||
f.Set(reflect.Append(f, results...))
|
||||
} else {
|
||||
f.Set(reflect.MakeSlice(f.Type(), 0, 0))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -90,6 +90,8 @@ func TestPreload(t *testing.T) {
|
|||
}
|
||||
} else if len(user.Emails) != 0 {
|
||||
t.Errorf("should not preload any emails for other users when with condition")
|
||||
} else if user.Emails == nil {
|
||||
t.Errorf("should return an empty slice to indicate zero results")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -592,8 +594,14 @@ func TestNestedPreload9(t *testing.T) {
|
|||
},
|
||||
Level2_1: Level2_1{
|
||||
Level1s: []Level1{
|
||||
{Value: "value3-3"},
|
||||
{Value: "value4-4"},
|
||||
{
|
||||
Value: "value3-3",
|
||||
Level0s: []Level0{},
|
||||
},
|
||||
{
|
||||
Value: "value4-4",
|
||||
Level0s: []Level0{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -657,6 +665,7 @@ func TestNestedPreload10(t *testing.T) {
|
|||
},
|
||||
{
|
||||
Value: "bar 2",
|
||||
LevelA3s: []*LevelA3{},
|
||||
},
|
||||
}
|
||||
for _, levelA2 := range want {
|
||||
|
|
Loading…
Reference in New Issue