Return id assumption for simple polymorphic Collection#model factories.

Also, add tests to make sure it doesn't break in the future.
This commit is contained in:
Casey Foster
2014-03-05 07:48:27 -06:00
parent e0233d8062
commit 3f7fbdeec6
2 changed files with 53 additions and 1 deletions

View File

@@ -703,6 +703,7 @@
var toAdd = [], toRemove = [], modelMap = {};
var add = options.add, merge = options.merge, remove = options.remove;
var order = !sortable && add && remove ? [] : false;
var targetProto = this.model.prototype;
// Turn bare objects into model references, and prevent invalid models
// from being added.
@@ -710,8 +711,10 @@
attrs = models[i] || {};
if (attrs instanceof Model) {
id = model = attrs;
} else if (targetProto.generateId) {
id = targetProto.generateId(attrs);
} else {
id = this.model.prototype.generateId(attrs);
id = attrs[targetProto.idAttribute || Model.prototype.idAttribute];
}
// If a duplicate is found, prevent it from being added and

View File

@@ -1362,4 +1362,53 @@
equal(collection.get(1), collection.first());
});
test('Polymorphic models work with "simple" constructors', function () {
var A = Backbone.Model.extend();
var B = Backbone.Model.extend();
var C = Backbone.Collection.extend({
model: function (attrs) {
return attrs.type === 'a' ? new A(attrs) : new B(attrs);
}
});
var collection = new C([{id: 1, type: 'a'}, {id: 2, type: 'b'}]);
equal(collection.length, 2);
ok(collection.at(0) instanceof A);
equal(collection.at(0).id, 1);
ok(collection.at(1) instanceof B);
equal(collection.at(1).id, 2);
});
test('Polymorphic models work with "advanced" constructors', function () {
var A = Backbone.Model.extend();
var B = Backbone.Model.extend();
var C = Backbone.Collection.extend({
model: Backbone.Model.extend({
constructor: function (attrs) {
return attrs.type === 'a' ? new A(attrs) : new B(attrs);
},
idAttribute: '_id'
})
});
var collection = new C([{_id: 1, type: 'a'}, {_id: 2, type: 'b'}]);
equal(collection.length, 2);
ok(collection.at(0) instanceof A);
ok(collection.at(1) instanceof B);
C = Backbone.Collection.extend({
model: Backbone.Model.extend({
constructor: function (attrs) {
return attrs.type === 'a' ? new A(attrs) : new B(attrs);
},
generateId: function (attrs) {
return attrs.type + '-' + attrs.id;
}
})
});
collection = new C([{id: 1, type: 'a'}, {id: 1, type: 'b'}]);
equal(collection.length, 2);
ok(collection.at(0) instanceof A);
ok(collection.at(1) instanceof B);
});
})();