@@ -55,6 +55,37 @@ var camelize = Ember.String.camelize;
55
55
*/
56
56
var RESTSerializer = JSONSerializer . extend ( {
57
57
58
+ /**
59
+ `keyForPolymorphicType` can be used to define a custom key when
60
+ serializing and deserializing a polymorphic type. By default, the
61
+ returned key is `${key}Type`.
62
+
63
+ Example
64
+
65
+ ```app/serializers/post.js
66
+ import DS from 'ember-data';
67
+
68
+ export default DS.RESTSerializer.extend({
69
+ keyForPolymorphicType: function(key, relationship) {
70
+ var relationshipKey = this.keyForRelationship(key);
71
+
72
+ return 'type-' + relationshipKey;
73
+ }
74
+ });
75
+ ```
76
+
77
+ @method keyForPolymorphicType
78
+ @param {String } key
79
+ @param {String } typeClass
80
+ @param {String } method
81
+ @return {String } normalized key
82
+ */
83
+ keyForPolymorphicType : function ( key , typeClass , method ) {
84
+ var relationshipKey = this . keyForRelationship ( key ) ;
85
+
86
+ return `${ relationshipKey } Type` ;
87
+ } ,
88
+
58
89
/**
59
90
Normalizes a part of the JSON payload returned by
60
91
the server. You should override this method, munge the hash
@@ -672,7 +703,7 @@ var RESTSerializer = JSONSerializer.extend({
672
703
673
704
/**
674
705
You can use this method to customize how polymorphic objects are serialized.
675
- By default the JSON Serializer creates the key by appending `Type` to
706
+ By default the REST Serializer creates the key by appending `Type` to
676
707
the attribute and value from the model's camelcased model name.
677
708
678
709
@method serializePolymorphicType
@@ -683,12 +714,75 @@ var RESTSerializer = JSONSerializer.extend({
683
714
serializePolymorphicType : function ( snapshot , json , relationship ) {
684
715
var key = relationship . key ;
685
716
var belongsTo = snapshot . belongsTo ( key ) ;
717
+ var typeKey = this . keyForPolymorphicType ( key , relationship . type , 'serialize' ) ;
718
+
719
+ // old way of getting the key for the polymorphic type
686
720
key = this . keyForAttribute ? this . keyForAttribute ( key , "serialize" ) : key ;
721
+ key = `${ key } Type` ;
722
+
723
+ // The old way of serializing the type of a polymorphic record used
724
+ // `keyForAttribute`, which is not correct. The next code checks if the old
725
+ // way is used and if it differs from the new way of using
726
+ // `keyForPolymorphicType`. If this is the case, a deprecation warning is
727
+ // logged and the old way is restored (so nothing breaks).
728
+ if ( key !== typeKey && this . keyForPolymorphicType === RESTSerializer . prototype . keyForPolymorphicType ) {
729
+ Ember . deprecate ( "The key to serialize the type of a polymorphic record is created via keyForAttribute which has been deprecated. Use the keyForPolymorphicType hook instead." , false , {
730
+ id : 'ds.rest-serializer.deprecated-key-for-polymorphic-type' ,
731
+ until : '3.0.0'
732
+ } ) ;
733
+
734
+ typeKey = key ;
735
+ }
736
+
687
737
if ( Ember . isNone ( belongsTo ) ) {
688
- json [ key + "Type" ] = null ;
738
+ json [ typeKey ] = null ;
689
739
} else {
690
- json [ key + "Type" ] = Ember . String . camelize ( belongsTo . modelName ) ;
740
+ json [ typeKey ] = camelize ( belongsTo . modelName ) ;
741
+ }
742
+ } ,
743
+
744
+ /**
745
+ You can use this method to customize how a polymorphic relationship should
746
+ be extracted.
747
+
748
+ @method extractPolymorphicRelationship
749
+ @param {Object } relationshipType
750
+ @param {Object } relationshipHash
751
+ @param {Object } relationshipOptions
752
+ @return {Object }
753
+ */
754
+ extractPolymorphicRelationship : function ( relationshipType , relationshipHash , relationshipOptions ) {
755
+ var { key, resourceHash, relationshipMeta } = relationshipOptions ;
756
+
757
+ // A polymorphic belongsTo relationship can be present in the payload
758
+ // either in the form where the `id` and the `type` are given:
759
+ //
760
+ // {
761
+ // message: { id: 1, type: 'post' }
762
+ // }
763
+ //
764
+ // or by the `id` and a `<relationship>Type` attribute:
765
+ //
766
+ // {
767
+ // message: 1,
768
+ // messageType: 'post'
769
+ // }
770
+ //
771
+ // The next code checks if the latter case is present and returns the
772
+ // corresponding JSON-API representation. The former case is handled within
773
+ // the base class JSONSerializer.
774
+ var isPolymorphic = relationshipMeta . options . polymorphic ;
775
+ var typeProperty = this . keyForPolymorphicType ( key , relationshipType , 'deserialize' ) ;
776
+
777
+ if ( isPolymorphic && resourceHash . hasOwnProperty ( typeProperty ) && typeof relationshipHash !== 'object' ) {
778
+ let type = this . modelNameFromPayloadKey ( resourceHash [ typeProperty ] ) ;
779
+ return {
780
+ id : relationshipHash ,
781
+ type : type
782
+ } ;
691
783
}
784
+
785
+ return this . _super ( ...arguments ) ;
692
786
}
693
787
} ) ;
694
788
0 commit comments