diff --git a/addon/adapters/firebase.js b/addon/adapters/firebase.js index dd7d1234..49a390e2 100644 --- a/addon/adapters/firebase.js +++ b/addon/adapters/firebase.js @@ -410,7 +410,6 @@ export default DS.Adapter.extend(Waitable, { updateRecord(store, typeClass, snapshot) { var recordRef = this._getAbsoluteRef(snapshot.record); var recordCache = this._getRecordCache(typeClass, snapshot.id); - var pathPieces = recordRef.path.toString().split('/'); var lastPiece = pathPieces[pathPieces.length-1]; var serializedRecord = snapshot.serialize({ @@ -418,38 +417,52 @@ export default DS.Adapter.extend(Waitable, { }); return new Promise((resolve, reject) => { - var savedRelationships = Ember.A(); + var relationshipsToSave = []; + // first we remove all relationships data from the serialized record, we backup the + // removed data so that we can save it at a later stage. snapshot.record.eachRelationship((key, relationship) => { - var save; - if (relationship.kind === 'hasMany') { - if (serializedRecord[key]) { - save = this._saveHasManyRelationship(store, typeClass, relationship, serializedRecord[key], recordRef, recordCache); - savedRelationships.push(save); - // Remove the relationship from the serializedRecord because otherwise we would clobber the entire hasMany - delete serializedRecord[key]; - } - } else { - if (this.isRelationshipEmbedded(store, typeClass.modelName, relationship) && serializedRecord[key]) { - save = this._saveEmbeddedBelongsToRecord(store, typeClass, relationship, serializedRecord[key], recordRef); - savedRelationships.push(save); - delete serializedRecord[key]; + const data = serializedRecord[key]; + const isEmbedded = this.isRelationshipEmbedded(store, typeClass.modelName, relationship); + const hasMany = relationship.kind === 'hasMany'; + if (hasMany || isEmbedded) { + if (!Ember.isNone(data)) { + relationshipsToSave.push({ + data:data, + relationship:relationship, + isEmbedded:isEmbedded, + hasMany:hasMany + }); } + delete serializedRecord[key]; } }); - - var relationshipsPromise = Ember.RSVP.allSettled(savedRelationships); - var recordPromise = this._updateRecord(recordRef, serializedRecord); - - Ember.RSVP.hashSettled({relationships: relationshipsPromise, record: recordPromise}).then((promises) => { - var rejected = Ember.A(promises.relationships.value).filterBy('state', 'rejected'); - if (promises.record.state === 'rejected') { - rejected.push(promises.record); - } - // Throw an error if any of the relationships failed to save + var reportError = (errors) => { + var error = new Error(`Some errors were encountered while saving ${typeClass} ${snapshot.id}`); + error.errors = errors; + reject(error); + }; + this._updateRecord(recordRef, serializedRecord).then(() => { + // and now we construct the list of promise to save relationships. + var savedRelationships = relationshipsToSave.map((relationshipToSave) => { + const data = relationshipToSave.data; + const relationship = relationshipToSave.relationship; + if (relationshipToSave.hasMany) { + return this._saveHasManyRelationship(store, typeClass, relationship, data, recordRef, recordCache); + } else { + // embedded belongsTo, we need to fill in the informations. + if (relationshipToSave.isEmbedded) { + return this._saveEmbeddedBelongsToRecord(store, typeClass, relationship, data, recordRef); + } + } + } + ); + return Ember.RSVP.allSettled(savedRelationships); + }).catch((e) => { + reportError([e]); + }).then((results) => { + var rejected = Ember.A(results).filterBy('state', 'rejected'); if (rejected.length !== 0) { - var error = new Error(`Some errors were encountered while saving ${typeClass} ${snapshot.id}`); - error.errors = Ember.A(rejected).mapBy('reason'); - reject(error); + reportError(rejected.mapBy('reason').toArray()); } else { resolve(); }