diff --git a/backbone-relational.js b/backbone-relational.js index ce7ae2c5..898aa099 100644 --- a/backbone-relational.js +++ b/backbone-relational.js @@ -755,10 +755,20 @@ this.related = attr; } // Otherwise, 'attr' should be an array of related object ids. - // Re-use the current 'this.related' if it is a Backbone.Collection. + // Re-use the current 'this.related' if it is a Backbone.Collection, and remove any current entries. + // Otherwise, create a new collection. else { - var coll = this.related instanceof Backbone.Collection ? this.related : new this.collectionType(); - this.setRelated( this.prepareCollection( coll ) ); + var coll; + + if ( this.related instanceof Backbone.Collection ) { + coll = this.related; + coll.reset( [], { silent: true } ); + } + else { + coll = this.prepareCollection( new this.collectionType() ); + } + + this.setRelated( coll ); this.findRelated( options ); } diff --git a/test/tests.js b/test/tests.js index 6b2bce94..2ee3a5aa 100644 --- a/test/tests.js +++ b/test/tests.js @@ -38,10 +38,15 @@ $(document).ready(function() { return url; }; - - + + + /** + * 'Zoo' + */ + window.Zoo = Backbone.RelationalModel.extend({ - relations: [{ + relations: [ + { type: Backbone.HasMany, key: 'animals', relatedModel: 'Animal', @@ -50,7 +55,13 @@ $(document).ready(function() { key: 'livesIn', includeInJSON: 'id' } - }] + }, + { // A simple HasMany without recursive relation + type: Backbone.HasMany, + key: 'visitors', + relatedModel: 'Visitor' + } + ] }); window.Animal = Backbone.RelationalModel.extend({ @@ -68,6 +79,12 @@ $(document).ready(function() { model: Animal }); + window.Visitor = Backbone.RelationalModel.extend(); + + + /** + * House/Person/Job/Company + */ window.House = Backbone.RelationalModel.extend({ relations: [{ @@ -86,7 +103,8 @@ $(document).ready(function() { }); window.Person = Backbone.RelationalModel.extend({ - relations: [{ + relations: [ + { // Create a cozy, recursive, one-to-one relationship type: Backbone.HasOne, key: 'likesALot', @@ -151,6 +169,7 @@ $(document).ready(function() { }); + window.Node = Backbone.RelationalModel.extend({ relations: [{ type: Backbone.HasOne, @@ -1114,7 +1133,7 @@ $(document).ready(function() { }); // Add job1 and job2 to the 'Person' side of the relation - var jobs = person1.get('jobs'); + var jobs = person1.get( 'jobs' ); jobs.add( job1 ); ok( jobs.length === 1, "jobs.length is 1" ); @@ -1169,6 +1188,23 @@ $(document).ready(function() { ok( ourHouse.get( 'occupants' ).id === undefined ); }); + + test( "Setting a new collection or array of ids updates the relation", function() { + var zoo = new Zoo(); + + var visitors = [ + { name: 'Paul' } + ]; + + zoo.set( 'visitors', visitors ); + + equal( zoo.get( 'visitors' ).length, 1 ); + + zoo.set( 'visitors', [] ); + + equal( zoo.get( 'visitors' ).length, 0 ); + }); + test( "Setting a custom collection in 'collectionType' uses that collection for instantiation", function() { var zoo = new Zoo(); @@ -1188,7 +1224,7 @@ $(document).ready(function() { ok( zoo.get( 'animals' ) instanceof AnimalCollection ); }); - test( "Settings a new collection maintains that collection's current 'models'", function() { + test( "Setting a new collection maintains that collection's current 'models'", function() { var zoo = new Zoo(); var animals = new AnimalCollection([ @@ -1211,7 +1247,7 @@ $(document).ready(function() { equal( zoo.get( 'animals' ).length, 3 ); }); - test( "Models found in 'findRelated' are all added in one go (and 'sort' will only be called once)", function() { + test( "Models found in 'findRelated' are all added in one go (so 'sort' will only be called once)", function() { var count = 0, sort = Backbone.Collection.prototype.sort;