@@ -616,174 +616,9 @@ func visitModelNode(model interface{}, included *map[string]*Node,
616
616
break
617
617
}
618
618
} 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
787
622
}
788
623
} else if annotation == annotationLinks {
789
624
// Nothing. Ignore this field, as Links fields are only for unmarshaling requests.
0 commit comments