Skip to content

Commit 5814468

Browse files
authored
Update response.go
1 parent 5dd72ce commit 5814468

File tree

1 file changed

+3
-168
lines changed

1 file changed

+3
-168
lines changed

response.go

Lines changed: 3 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -616,174 +616,9 @@ func visitModelNode(model interface{}, included *map[string]*Node,
616616
break
617617
}
618618
} else if annotation == annotationRelation || annotation == annotationPolyRelation {
619-
var omitEmpty bool
620-
621-
//add support for 'omitempty' struct tag for marshaling as absent
622-
if len(args) > 2 {
623-
omitEmpty = args[2] == annotationOmitEmpty
624-
}
625-
626-
// Handle NullableRelationship[T]
627-
if strings.HasPrefix(fieldValue.Type().Name(), "NullableRelationship[") {
628-
629-
if fieldValue.MapIndex(reflect.ValueOf(false)).IsValid() {
630-
innerTypeIsSlice := fieldValue.MapIndex(reflect.ValueOf(false)).Type().Kind() == reflect.Slice
631-
// handle explicit null
632-
if innerTypeIsSlice {
633-
node.Relationships[args[1]] = json.RawMessage("[]")
634-
} else {
635-
node.Relationships[args[1]] = json.RawMessage("{\"data\":null}")
636-
}
637-
continue
638-
} else if fieldValue.MapIndex(reflect.ValueOf(true)).IsValid() {
639-
// handle value
640-
fieldValue = fieldValue.MapIndex(reflect.ValueOf(true))
641-
}
642-
}
643-
644-
isSlice := fieldValue.Type().Kind() == reflect.Slice
645-
if omitEmpty &&
646-
(isSlice && fieldValue.Len() < 1 ||
647-
(!isSlice && fieldValue.IsNil())) {
648-
continue
649-
}
650-
651-
if annotation == annotationPolyRelation {
652-
// for polyrelation, we'll snoop out the actual relation model
653-
// through the choice type value by choosing the first non-nil
654-
// field that has a jsonapi type annotation and overwriting
655-
// `fieldValue` so normal annotation-assisted marshaling
656-
// can continue
657-
if !isSlice {
658-
choiceValue := fieldValue
659-
660-
// must be a pointer type
661-
if choiceValue.Type().Kind() != reflect.Ptr {
662-
er = ErrUnexpectedType
663-
break
664-
}
665-
666-
if choiceValue.IsNil() {
667-
fieldValue = reflect.ValueOf(nil)
668-
}
669-
structValue := choiceValue.Elem()
670-
671-
// Short circuit if field is omitted from model
672-
if !structValue.IsValid() {
673-
break
674-
}
675-
676-
if found, err := selectChoiceTypeStructField(structValue); err == nil {
677-
fieldValue = found
678-
}
679-
} else {
680-
// A slice polyrelation field can be... polymorphic... meaning
681-
// that we might snoop different types within each slice element.
682-
// Each snooped value will added to this collection and then
683-
// the recursion will take care of the rest. The only special case
684-
// is nil. For that, we'll just choose the first
685-
collection := make([]interface{}, 0)
686-
687-
for i := 0; i < fieldValue.Len(); i++ {
688-
itemValue := fieldValue.Index(i)
689-
// Once again, must be a pointer type
690-
if itemValue.Type().Kind() != reflect.Ptr {
691-
er = ErrUnexpectedType
692-
break
693-
}
694-
695-
if itemValue.IsNil() {
696-
er = ErrUnexpectedNil
697-
break
698-
}
699-
700-
structValue := itemValue.Elem()
701-
702-
if found, err := selectChoiceTypeStructField(structValue); err == nil {
703-
collection = append(collection, found.Interface())
704-
}
705-
}
706-
707-
if er != nil {
708-
break
709-
}
710-
711-
fieldValue = reflect.ValueOf(collection)
712-
}
713-
}
714-
715-
var relLinks *Links
716-
if linkableModel, ok := model.(RelationshipLinkable); ok {
717-
relLinks = linkableModel.JSONAPIRelationshipLinks(args[1])
718-
}
719-
720-
var relMeta *Meta
721-
if metableModel, ok := model.(RelationshipMetable); ok {
722-
relMeta = metableModel.JSONAPIRelationshipMeta(args[1])
723-
}
724-
725-
if isSlice {
726-
// to-many relationship
727-
relationship, err := visitModelNodeRelationships(
728-
fieldValue,
729-
included,
730-
sideload,
731-
)
732-
if err != nil {
733-
er = err
734-
break
735-
}
736-
relationship.Links = relLinks
737-
relationship.Meta = relMeta
738-
739-
if sideload {
740-
shallowNodes := []*Node{}
741-
for _, n := range relationship.Data {
742-
appendIncluded(included, n)
743-
shallowNodes = append(shallowNodes, toShallowNode(n))
744-
}
745-
746-
node.Relationships[args[1]] = &RelationshipManyNode{
747-
Data: shallowNodes,
748-
Links: relationship.Links,
749-
Meta: relationship.Meta,
750-
}
751-
} else {
752-
node.Relationships[args[1]] = relationship
753-
}
754-
} else {
755-
// to-one relationships
756-
757-
// Handle null relationship case
758-
if fieldValue.IsNil() {
759-
node.Relationships[args[1]] = &RelationshipOneNode{Data: nil}
760-
continue
761-
}
762-
763-
relationship, err := visitModelNode(
764-
fieldValue.Interface(),
765-
included,
766-
sideload,
767-
)
768-
if err != nil {
769-
er = err
770-
break
771-
}
772-
773-
if sideload {
774-
appendIncluded(included, relationship)
775-
node.Relationships[args[1]] = &RelationshipOneNode{
776-
Data: toShallowNode(relationship),
777-
Links: relLinks,
778-
Meta: relMeta,
779-
}
780-
} else {
781-
node.Relationships[args[1]] = &RelationshipOneNode{
782-
Data: relationship,
783-
Links: relLinks,
784-
Meta: relMeta,
785-
}
786-
}
619+
er = visitModelNodeRelation(model, annotation, args, node, fieldValue, included, sideload)
620+
if er != nil {
621+
break
787622
}
788623
} else if annotation == annotationLinks {
789624
// Nothing. Ignore this field, as Links fields are only for unmarshaling requests.

0 commit comments

Comments
 (0)