Skip to content

Commit

Permalink
Merge pull request #365 from olivierchatry/relationships-saved-last
Browse files Browse the repository at this point in the history
relation ships are now saved after the record itself
  • Loading branch information
tstirrat committed Feb 17, 2016
2 parents 3e5b1b0 + 4d448a6 commit 74cd3b3
Showing 1 changed file with 41 additions and 28 deletions.
69 changes: 41 additions & 28 deletions addon/adapters/firebase.js
Original file line number Diff line number Diff line change
Expand Up @@ -410,46 +410,59 @@ 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({
includeId: (lastPiece !== snapshot.id) // record has no firebase `key` in path
});

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();
}
Expand Down

0 comments on commit 74cd3b3

Please sign in to comment.