Using ember-resource with couchdb - how can i save my documents?
- by Thomas Herrmann
I am implementing an application using ember.js and couchdb. I choose ember-resource as database access layer because it nicely supports nested JSON documents.
Since couchdb uses the attribute _rev for optimistic locking in every document, this attribute has to be updated in my application after saving the data to the couchdb.
My idea to implement this is to reload the data right after saving to the database and get the new _rev back with the rest of the document.
Here is my code for this:
// Since we use CouchDB, we have to make sure that we invalidate and re-fetch
// every document right after saving it. CouchDB uses an optimistic locking
// scheme based on the attribute "_rev" in the documents, so we reload it in
// order to have the correct _rev value.
didSave: function() {
this._super.apply(this, arguments);
this.forceReload();
},
// reload resource after save is done, expire to make reload really do something
forceReload: function() {
this.expire(); // Everything OK up to this location
Ember.run.next(this, function() {
this.fetch() // Sub-Document is reset here, and *not* refetched!
.fail(function(error) {
App.displayError(error);
})
.done(function() {
App.log("App.Resource.forceReload fetch done, got revision " + self.get('_rev'));
});
});
}
This works for most cases, but if i have a nested model, the sub-model is replaced with the old version of the data just before the fetch is executed!
Interestingly enough, the correct (updated) data is stored in the database and the wrong (old) data is in the memory model after the fetch, although the _rev attribut is correct (as well as all attributes of the main object).
Here is a part of my object definition:
App.TaskDefinition = App.Resource.define({
url: App.dbPrefix + 'courseware',
schema: {
id: String,
_rev: String,
type: String,
name: String,
comment: String,
task: {
type: 'App.Task',
nested: true
}
}
});
App.Task = App.Resource.define({
schema: {
id: String,
title: String,
description: String,
startImmediate: Boolean,
holdOnComment: Boolean,
..... // other attributes and sub-objects
}
});
Any ideas where the problem might be?
Thank's a lot for any suggestion!
Kind regards,
Thomas