Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Much asked-for change. Instead of throwing an early error when adding…

… duplicate models, Backbone will simply skip them instead.
  • Loading branch information...
commit 18fba5772430f667c0d3cfb88d880039381c25fa 1 parent b1e2e69
Jeremy Ashkenas authored
Showing with 22 additions and 18 deletions.
  1. +11 −3 backbone.js
  2. +11 −15 test/collection.js
14 backbone.js
View
@@ -501,7 +501,7 @@
// Add a model, or list of models to the set. Pass **silent** to avoid
// firing the `add` event for every new model.
add: function(models, options) {
- var i, index, length, model, cid, id, cids = {}, ids = {};
+ var i, index, length, model, cid, id, cids = {}, ids = {}, dups = [];
options || (options = {});
models = _.isArray(models) ? models.slice() : [models];
@@ -513,14 +513,21 @@
}
if (cids[cid = model.cid] || this._byCid[cid] ||
(((id = model.id) != null) && (ids[id] || this._byId[id]))) {
- throw new Error("Can't add the same model to a collection twice");
+ dups.push(i);
+ continue;
}
cids[cid] = ids[id] = model;
}
+ // Remove duplicates.
+ i = dups.length;
+ while (i--) {
+ models.splice(dups[i], 1);
+ }
+
// Listen to added models' events, and index models for lookup by
// `id` and by `cid`.
- for (i = 0; i < length; i++) {
+ for (i = 0, length = models.length; i < length; i++) {
(model = models[i]).on('all', this._onModelEvent, this);
this._byCid[model.cid] = model;
if (model.id != null) this._byId[model.id] = model;
@@ -705,6 +712,7 @@
// Prepare a model or hash of attributes to be added to this collection.
_prepareModel: function(model, options) {
+ options || (options = {});
if (!(model instanceof Backbone.Model)) {
var attrs = model;
options.collection = this;
26 test/collection.js
View
@@ -124,22 +124,15 @@ $(document).ready(function() {
});
test("Collection: can't add model to collection twice", function() {
- raises(function(){
- // no id, same cid
- var a2 = new Backbone.Model({label: a.label});
- a2.cid = a.cid;
- col.push(a2);
- ok(false, "duplicate; expected add to fail");
- }, "Can't add the same model to a collection twice");
+ var col = new Backbone.Collection([{id: 1}, {id: 2}, {id: 1}, {id: 2}, {id: 3}]);
+ equal(col.pluck('id').join(' '), '1 2 3');
});
test("Collection: can't add different model with same id to collection twice", function() {
- raises(function(){
- var col = new Backbone.Collection;
- col.unshift({id: 101});
- col.add({id: 101});
- ok(false, "duplicate; expected add to fail");
- }, "Can't add the same model to a collection twice");
+ var col = new Backbone.Collection;
+ col.unshift({id: 101});
+ col.add({id: 101});
+ equal(col.length, 1);
});
test("Collection: add model to multiple collections", function() {
@@ -518,8 +511,11 @@ $(document).ready(function() {
test("Collection: multiple copies of the same model", function() {
var col = new Backbone.Collection();
var model = new Backbone.Model();
- raises(function() { col.add([model, model]); });
- raises(function() { col.add([{id: 1}, {id: 1}]); });
+ col.add([model, model]);
+ equal(col.length, 1);
+ col.add([{id: 1}, {id: 1}]);
+ equal(col.length, 2);
+ equal(col.last().id, 1);
});
test("#964 - collection.get return in consistent", function() {
Please sign in to comment.
Something went wrong with that request. Please try again.