Skip to content
This repository was archived by the owner on Aug 25, 2018. It is now read-only.

Commit 7465643

Browse files
committed
Backbone.Model#idAttribute (limited) support. SPECS MISSING.
1 parent 746d812 commit 7465643

File tree

3 files changed

+35
-22
lines changed

3 files changed

+35
-22
lines changed

src/backbonefire.js

+29-19
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@
164164
* primitive - Throw error, primitives cannot be synced
165165
* null - Create blank object and assign id
166166
*/
167-
Backbone.Firebase._checkId = function(snap) {
167+
Backbone.Firebase._checkId = function(snap, idAttribute) {
168168
var model = snap.val();
169169

170170
// if the model is a primitive throw an error
@@ -180,7 +180,7 @@
180180
}
181181

182182
// set the id to the snapshot's key
183-
model.id = Backbone.Firebase._getKey(snap);
183+
model[idAttribute] = Backbone.Firebase._getKey(snap);
184184

185185
return model;
186186
};
@@ -348,7 +348,7 @@
348348
}
349349

350350
},
351-
351+
352352
sync: function(method, model, options) {
353353
Backbone.Firebase.sync(method, model, options);
354354
},
@@ -359,7 +359,7 @@
359359
_setId: function(snap) {
360360
// if the item new set the name to the id
361361
if(this.isNew()) {
362-
this.set('id', Backbone.Firebase._getKey(snap), { silent: true });
362+
this.set(this.idAttribute, Backbone.Firebase._getKey(snap), { silent: true });
363363
}
364364
},
365365

@@ -376,7 +376,7 @@
376376
* by comparing the keys that have been removed.
377377
*/
378378
_unsetAttributes: function(snap) {
379-
var newModel = Backbone.Firebase._checkId(snap);
379+
var newModel = Backbone.Firebase._checkId(snap, this.idAttribute);
380380

381381
if (typeof newModel === 'object' && newModel !== null) {
382382
var diff = _.difference(_.keys(this.attributes), _.keys(newModel));
@@ -399,7 +399,7 @@
399399
var modelObj = model.changedAttributes();
400400
_.each(model.changed, function(value, key) {
401401
if (typeof value === 'undefined' || value === null) {
402-
if (key == 'id') {
402+
if (key == model.idAttribute) {
403403
delete modelObj[key];
404404
} else {
405405
modelObj[key] = null;
@@ -438,7 +438,8 @@
438438
* Backbone.Firebase.sync with the correct method.
439439
*/
440440
create: function(model, options) {
441-
model.id = Backbone.Firebase._getKey(this.firebase.push());
441+
// XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute
442+
model[this.idAttribute] = Backbone.Firebase._getKey(this.firebase.push());
442443
options = _.extend({ autoSync: false }, options);
443444
return Backbone.Collection.prototype.create.call(this, model, options);
444445
},
@@ -448,7 +449,8 @@
448449
* Backbone.Firebase.sync with the correct method.
449450
*/
450451
add: function(model, options) {
451-
model.id = Backbone.Firebase._getKey(this.firebase.push());
452+
// XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute
453+
model[this.idAttribute] = Backbone.Firebase._getKey(this.firebase.push());
452454
options = _.extend({ autoSync: false }, options);
453455
return Backbone.Collection.prototype.add.call(this, model, options);
454456
},
@@ -503,7 +505,6 @@
503505
// Defer the listener incase the data is cached, because
504506
// then the once call would be synchronous
505507
_.defer(_.bind(function() {
506-
507508
this.firebase.once('value', function() {
508509
// indicate that the call has been received from the server
509510
// and the data has successfully loaded
@@ -541,7 +542,8 @@
541542
this._suppressEvent = true;
542543
}
543544

544-
var childRef = this.firebase.ref().child(model.id);
545+
// XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute
546+
var childRef = this.firebase.ref().child(model[this.idAttribute]);
545547
childRef.set(model, _.bind(options.success, model));
546548
}
547549

@@ -568,7 +570,8 @@
568570

569571
for (var i = 0; i < parsed.length; i++) {
570572
var model = parsed[i];
571-
var childRef = this.firebase.child(model.id);
573+
// XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute
574+
var childRef = this.firebase.child(model[this.idAttribute]);
572575
if (options.silent === true) {
573576
this._suppressEvent = true;
574577
}
@@ -628,9 +631,8 @@
628631
for (var i = 0; i < models.length; i++) {
629632
var model = models[i];
630633

631-
if (!model.id) {
632-
model.id = Backbone.Firebase._getKey(this.firebase.push());
633-
}
634+
// XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute
635+
model[this.idAttribute] = model[this.idAttribute] || Backbone.Firebase._getKey(this.firebase.push());
634636

635637
// call Backbone's prepareModel to apply options
636638
model = Backbone.Collection.prototype._prepareModel.call(
@@ -649,15 +651,16 @@
649651
},
650652

651653
_childAdded: function(snap) {
652-
var model = Backbone.Firebase._checkId(snap);
654+
// XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute
655+
var model = Backbone.Firebase._checkId(snap, this.idAttribute);
653656

654657
if (this._suppressEvent === true) {
655658
this._suppressEvent = false;
656659
Backbone.Collection.prototype.add.call(this, [model], {silent: true});
657660
} else {
658661
Backbone.Collection.prototype.add.call(this, [model]);
659662
}
660-
this.get(model.id)._remoteAttributes = model;
663+
this.get(model[this.idAttribute])._remoteAttributes = model;
661664
},
662665

663666
// TODO: child_moved is emitted when the priority for a child is changed, so it
@@ -669,10 +672,12 @@
669672
// when a model has changed remotely find differences between the
670673
// local and remote data and apply them to the local model
671674
_childChanged: function(snap) {
672-
var model = Backbone.Firebase._checkId(snap);
675+
// XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute
676+
var idAttribute = this.idAttribute;
677+
var model = Backbone.Firebase._checkId(snap, idAttribute);
673678

674679
var item = _.find(this.models, function(child) {
675-
return child.id == model.id;
680+
return child.id == model[idAttribute];
676681
});
677682

678683
if (!item) {
@@ -701,7 +706,8 @@
701706
// remove an item from the collection when removed remotely
702707
// provides the ability to remove siliently
703708
_childRemoved: function(snap) {
704-
var model = Backbone.Firebase._checkId(snap);
709+
// XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute
710+
var model = Backbone.Firebase._checkId(snap, this.idAttribute);
705711

706712
if (this._suppressEvent === true) {
707713
this._suppressEvent = false;
@@ -827,6 +833,10 @@
827833
SyncCollection.apply(this, arguments);
828834
}
829835

836+
// XXX before breaking model prototype: worked around this.model.prototype.idAttribute with this.idAttribute
837+
this.idAttribute = this.idAttribute || BaseModel.prototype.idAttribute;
838+
839+
// XXX breaking the model prototype
830840
// Intercept the given model and give it a firebase ref.
831841
// Have it listen to local changes silently. When attributes
832842
// are unset, the callback will set them to null so that they

test/specs/collection_test.js

+3
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ describe('Backbone.Firebase.Collection', function() {
194194
User = Backbone.Model.extend({}),
195195
Users = Backbone.Firebase.Collection.extend({
196196
url: 'Mock://',
197+
idAttribute: User.prototype.idAttribute,
197198
initialize: function(models, options) {
198199
this.model = function(attrs, opts) {
199200
return new User(_.extend(attrs, { addedFromCollection: true}), opts);
@@ -227,6 +228,7 @@ describe('Backbone.Firebase.Collection', function() {
227228
User = Backbone.Model.extend({}),
228229
Users = Backbone.Firebase.Collection.extend({
229230
url: 'Mock://',
231+
idAttribute: User.prototype.idAttribute,
230232
initialize: function(models, options) {
231233
this.model = function(attrs, opts) {
232234
return new User(_.extend(attrs, { addedFromCollection: true}), opts);
@@ -451,6 +453,7 @@ describe('Backbone.Firebase.Collection', function() {
451453
beforeEach(function() {
452454
var Collection = Backbone.Firebase.Collection.extend({
453455
url: 'Mock://',
456+
idAttribute: Backbone.Model.prototype.idAttribute,
454457
autoSync: true
455458
});
456459

test/specs/prototype_test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ describe('Backbone.Firebase', function() {
105105
}
106106
});
107107

108-
var model = Backbone.Firebase._checkId(mockSnap);
108+
var model = Backbone.Firebase._checkId(mockSnap, 'id');
109109

110110
expect(model.id).to.be.ok;
111111
model.id.should.equal(mockSnap.name());
@@ -118,7 +118,7 @@ describe('Backbone.Firebase', function() {
118118
val: 'hello'
119119
});
120120
try {
121-
var model = Backbone.Firebase._checkId(1);
121+
var model = Backbone.Firebase._checkId(1, 'id');
122122
} catch (err) {
123123
expect(err).to.be.ok
124124
}
@@ -130,7 +130,7 @@ describe('Backbone.Firebase', function() {
130130
name: '1',
131131
val: null
132132
});
133-
var model = Backbone.Firebase._checkId(mockSnap);
133+
var model = Backbone.Firebase._checkId(mockSnap, 'id');
134134
expect(model.id).to.be.ok;
135135
});
136136

0 commit comments

Comments
 (0)