Permalink
Browse files

Fix a bug where changing `id` causes reverseRelations not to be set up.

Setting (or changing) a model's `id` later could cause reverseRelations
to that model not to be set up, since these models were not notified.
  • Loading branch information...
1 parent c3a378b commit 025b9268ee147e08c2ed228989ba8934e7e4822a @PaulUithol committed Mar 28, 2013
Showing with 13 additions and 7 deletions.
  1. +10 −5 backbone-relational.js
  2. +3 −2 test/tests.js
View
@@ -421,10 +421,14 @@
/**
* Explicitly update a model's id in its store collection
* @param {Backbone.RelationalModel} model
- */
+ */
update: function( model ) {
var coll = this.getCollection( model );
+ // This triggers updating the lookup indices kept in a collection
coll._onModelEvent( 'change:' + model.idAttribute, model, coll );
+
+ // Trigger an event on model so related models (having the model's new id in their keyContents) can add it.
+ model.trigger( 'relational:change:id', model, coll );
},
/**
@@ -527,7 +531,7 @@
// When 'relatedModel' are created or destroyed, check if it affects this relation.
this.listenTo( this.instance, 'destroy', this.destroy )
- .listenTo( this.relatedCollection, 'relational:add', this.tryAddRelated )
+ .listenTo( this.relatedCollection, 'relational:add relational:change:id', this.tryAddRelated )
.listenTo( this.relatedCollection, 'relational:remove', this.removeRelated )
}
};
@@ -1342,7 +1346,8 @@
attributes[ key ] = value;
}
- var result = Backbone.Model.prototype.set.apply( this, arguments );
+ var prevId = this.id,
+ result = Backbone.Model.prototype.set.apply( this, arguments );
// Ideal place to set up relations :)
try {
@@ -1353,8 +1358,8 @@
this.initializeRelations( options );
}
- // Update the 'idAttribute' in Backbone.store if; we don't want it to miss an 'id' update due to {silent:true}
- else if ( attributes && this.idAttribute in attributes ) {
+ // Update the 'idAttribute'; we don't want the store to miss an 'id' update (due to {silent:true})
+ else if ( attributes && this.idAttribute in attributes && prevId !== attributes[ this.idAttribute ] ) {
Backbone.Relational.store.update( this );
}
View
@@ -2163,11 +2163,12 @@ $(document).ready(function() {
});
test( "Setting id on objects with reverse relations updates related collection correctly", function() {
- var zoo1 = new Zoo({ id: 2 });
+ var zoo1 = new Zoo();
ok( zoo1.get( 'animals' ).size() === 0, "zoo has no animals" );
- var lion = new Animal({ livesIn: 2 });
+ var lion = new Animal( { livesIn: 2 } );
+ zoo1.set( 'id', 2 );
ok( lion.get( 'livesIn' ) === zoo1, "zoo1 connected to lion" );
ok( zoo1.get( 'animals' ).length === 1, "zoo1 has one Animal" );

0 comments on commit 025b926

Please sign in to comment.