NOTE. This answer was written for Backbone v0.9. Backbone v1.0 has since been released, which contains the collection.set()
method described here . This will probably be the best solution.
I put together my own version of this on the weekend. I will post it here if anyone else finds this topic, but I will still be happy to see any other solutions that may be there.
I did this by changing the source of Backbone.js, which is not necessarily a great idea, but it was easy. There were two changes: first add this function to the Backbone.Collection prototype:
//**upsert** takes models and does an update-or-insert operation on them //So models that already exist are updated, and new models are added upsert: function (models, options) { var self = this; options || (options = {}); models = _.isArray(models) ? models.slice() : [models]; var addModels = []; _.each(models, function (newModel) { var n = self._prepareModel(newModel, options); var existingModel = self.get(n.id); if (existingModel) { existingModel.set(n, options); } else { addModels.push(n); } }); if (!_.isEmpty(addModels)) { self.add(addModels, options); } }
Then change one line in the Backbone.Collection.fetch () function to read:
collection[options.add ? 'add' : (options.upsert ? "upsert" : 'reset')](collection.parse(resp, xhr), options);
This allows you to call fetch({upsert:true})
to get the behavior I was looking for.
source share