@@ -16,7 +16,6 @@ const iterateRelations = function(record, relations, callback) {
16
16
let relatedRecord = record . get ( relationName ) ;
17
17
let manyToManyDeleted = record . manyToManyMarkedForDeletionModels ( relationName ) ;
18
18
19
-
20
19
if ( metadata . options . async !== false ) {
21
20
relatedRecord = relatedRecord . get ( 'content' ) ;
22
21
}
@@ -31,11 +30,10 @@ const isPresentObject = function(val) {
31
30
return val && Object . keys ( val ) . length > 0 ;
32
31
} ;
33
32
34
- const attributesFor = function ( record , isManyToManyDelete ) {
33
+ const attributesFor = function ( record ) {
35
34
let attrs = { } ;
36
35
37
36
let changes = record . changedAttributes ( ) ;
38
-
39
37
let serializer = record . store . serializerFor ( record . constructor . modelName ) ;
40
38
41
39
record . eachAttribute ( ( name /* meta */ ) => {
@@ -50,71 +48,115 @@ const attributesFor = function(record, isManyToManyDelete) {
50
48
}
51
49
} ) ;
52
50
53
- if ( record . get ( 'markedForDeletion' ) || isManyToManyDelete ) {
54
- attrs = { _delete : true } ;
55
- }
56
-
57
- if ( ! record . get ( 'isNew' ) && record . get ( 'markedForDestruction' ) ) {
58
- attrs = { _destroy : true } ;
59
- }
60
-
61
51
return attrs ;
62
52
} ;
63
53
64
54
const jsonapiPayload = function ( record , isManyToManyDelete ) {
65
- let attributes = attributesFor ( record , isManyToManyDelete ) ;
55
+ let attributes = attributesFor ( record ) ;
66
56
67
57
let payload = { type : record . jsonapiType ( ) } ;
68
58
69
59
if ( isPresentObject ( attributes ) ) {
70
60
payload . attributes = attributes ;
71
61
}
72
62
63
+ if ( record . get ( 'isNew' ) ) {
64
+ payload [ 'temp-id' ] = record . tempId ( ) ;
65
+ payload [ 'method' ] = 'create' ;
66
+ }
67
+ else if ( record . get ( 'markedForDestruction' ) ) {
68
+ payload [ 'method' ] = 'destroy' ;
69
+ }
70
+ else if ( record . get ( 'markedForDeletion' ) || isManyToManyDelete ) {
71
+ payload [ 'method' ] = 'disassociate' ;
72
+ }
73
+ else if ( record . get ( 'currentState.isDirty' ) ) {
74
+ payload [ 'method' ] = 'update' ;
75
+ }
76
+
73
77
if ( record . id ) {
74
78
payload . id = record . id ;
75
79
}
76
80
77
81
return payload ;
78
82
} ;
79
83
80
- const hasManyData = function ( relationName , relatedRecords , subRelations , manyToManyDeleted ) {
84
+ const payloadForInclude = function ( payload ) {
85
+ let payloadCopy = Ember . copy ( payload , true ) ;
86
+ delete ( payloadCopy . method ) ;
87
+
88
+ return payloadCopy ;
89
+ } ;
90
+
91
+ const payloadForRelationship = function ( payload ) {
92
+ let payloadCopy = Ember . copy ( payload , true ) ;
93
+ delete ( payloadCopy . attributes ) ;
94
+ delete ( payloadCopy . relationships ) ;
95
+
96
+ return payloadCopy ;
97
+ } ;
98
+
99
+ const addToIncludes = function ( payload , includedRecords ) {
100
+ let includedPayload = payloadForInclude ( payload ) ;
101
+
102
+ if ( ! includedPayload . attributes && ! isPresentObject ( includedPayload . relationships ) ) {
103
+ return ;
104
+ }
105
+
106
+ const alreadyIncluded = includedRecords . find ( ( includedRecord ) =>
107
+ includedPayload [ 'type' ] === includedRecord [ 'type' ] &&
108
+ ( ( includedPayload [ 'temp-id' ] && includedPayload [ 'temp-id' ] === includedRecord [ 'temp-id' ] ) ||
109
+ ( includedPayload [ 'id' ] && includedPayload [ 'id' ] === includedRecord [ 'id' ] ) )
110
+ ) !== undefined ;
111
+
112
+ if ( ! alreadyIncluded ) {
113
+ includedRecords . push ( includedPayload ) ;
114
+ }
115
+ } ;
116
+
117
+ const hasManyData = function ( relationName , relatedRecords , subRelations , manyToManyDeleted , includedRecords ) {
81
118
let payloads = [ ] ;
82
119
savedRecords [ relationName ] = [ ] ;
120
+
83
121
relatedRecords . forEach ( ( relatedRecord ) => {
84
122
let payload = jsonapiPayload ( relatedRecord , manyToManyDeleted && manyToManyDeleted . includes ( relatedRecord ) ) ;
85
- processRelationships ( subRelations , payload , relatedRecord ) ;
86
- payloads . push ( payload ) ;
123
+ processRelationships ( subRelations , payload , relatedRecord , includedRecords ) ;
124
+ addToIncludes ( payload , includedRecords ) ;
125
+
126
+ payloads . push ( payloadForRelationship ( payload ) ) ;
87
127
savedRecords [ relationName ] . push ( relatedRecord ) ;
88
128
} ) ;
89
129
return { data : payloads } ;
90
130
} ;
91
131
92
- const belongsToData = function ( relatedRecord , subRelations ) {
132
+ const belongsToData = function ( relatedRecord , subRelations , includedRecords ) {
93
133
let payload = jsonapiPayload ( relatedRecord ) ;
94
- processRelationships ( subRelations , payload , relatedRecord ) ;
95
- return { data : payload } ;
134
+ processRelationships ( subRelations , payload , relatedRecord , includedRecords ) ;
135
+ addToIncludes ( payload , includedRecords ) ;
136
+
137
+ return { data : payloadForRelationship ( payload ) } ;
96
138
} ;
97
139
98
- const processRelationship = function ( name , kind , relationData , subRelations , manyToManyDeleted , callback ) {
140
+ const processRelationship = function ( name , kind , relationData , subRelations , manyToManyDeleted , includedRecords , callback ) {
99
141
let payload = null ;
100
142
101
143
if ( kind === 'hasMany' ) {
102
- payload = hasManyData ( name , relationData , subRelations , manyToManyDeleted ) ;
144
+ payload = hasManyData ( name , relationData , subRelations , manyToManyDeleted , includedRecords ) ;
103
145
} else {
104
- payload = belongsToData ( relationData , subRelations ) ;
146
+ payload = belongsToData ( relationData , subRelations , includedRecords ) ;
105
147
}
106
148
107
149
if ( payload && payload . data ) {
108
150
callback ( payload ) ;
109
151
}
110
152
} ;
111
153
112
- const processRelationships = function ( relationshipHash , jsonData , record ) {
154
+ const processRelationships = function ( relationshipHash , jsonData , record , includedRecords ) {
113
155
if ( isPresentObject ( relationshipHash ) ) {
114
156
jsonData . relationships = { } ;
115
157
116
158
iterateRelations ( record , relationshipHash , ( name , kind , related , subRelations , manyToManyDeleted ) => {
117
- processRelationship ( name , kind , related , subRelations , manyToManyDeleted , ( payload ) => {
159
+ processRelationship ( name , kind , related , subRelations , manyToManyDeleted , includedRecords , ( payload ) => {
118
160
let serializer = record . store . serializerFor ( record . constructor . modelName ) ;
119
161
let serializedName = serializer . keyForRelationship ( name ) ;
120
162
jsonData . relationships [ serializedName ] = payload ;
@@ -148,7 +190,9 @@ const relationshipsDirective = function(value) {
148
190
export default Ember . Mixin . create ( {
149
191
serialize ( snapshot /*, options */ ) {
150
192
savedRecords = [ ] ;
193
+
151
194
let json = this . _super ( ...arguments ) ;
195
+ let includedRecords = [ ] ;
152
196
153
197
if ( snapshot . record . get ( 'emberDataExtensions' ) !== false ) {
154
198
delete ( json . data . relationships ) ;
@@ -180,7 +224,10 @@ export default Ember.Mixin.create({
180
224
}
181
225
182
226
let relationships = relationshipsDirective ( adapterOptions . relationships ) ;
183
- processRelationships ( relationships , json . data , snapshot . record ) ;
227
+ processRelationships ( relationships , json . data , snapshot . record , includedRecords ) ;
228
+ if ( includedRecords && includedRecords . length > 0 ) {
229
+ json . included = includedRecords ;
230
+ }
184
231
snapshot . record . set ( '__recordsJustSaved' , savedRecords ) ;
185
232
}
186
233
0 commit comments