From 53bdf73d457a871105dd5ff86071467187188e25 Mon Sep 17 00:00:00 2001 From: uglymunky Date: Fri, 6 Jun 2014 09:31:23 -0700 Subject: [PATCH 1/3] adds test case for #69 --- test/spec/backbone.siren.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/spec/backbone.siren.js b/test/spec/backbone.siren.js index be6ae3a..8a0ef3a 100644 --- a/test/spec/backbone.siren.js +++ b/test/spec/backbone.siren.js @@ -331,6 +331,19 @@ describe('Backbone.Siren: ', function () { }); + it('creates a new "self" collection if parsing a "current" collection and one does not already exist', function () { + var store = new Backbone.Siren.Store(); + + // Add a current collection to the store + var collection = Backbone.Siren.parseCollection(rawCurrentCollection, {store: store}); + var storedCurrentCollection = store.get(collection.link('current')); + var storedSelfCollection = store.get(collection.link('self')); + + expect(storedCurrentCollection).toBe(collection); + expect(storedCurrentCollection).not.toBe(storedSelfCollection); + }); + + it('leaves the matching, cached, "loaded" collection un-changed if parsing a "linked" collection', function () { var store = new Backbone.Siren.Store(); var collection = new Backbone.Siren.Collection(rawCollection, {store: store}); From 9d60bb7385da1df889a7729e710de8a4d0ea6625 Mon Sep 17 00:00:00 2001 From: uglymunky Date: Tue, 17 Jun 2014 02:03:07 -0700 Subject: [PATCH 2/3] #69 better caching of self and current collections --- src/backbone.siren.js | 51 +++++++++++++++++++------------- test/spec/backbone.siren.js | 59 +++++++++++++++++++++---------------- 2 files changed, 64 insertions(+), 46 deletions(-) diff --git a/src/backbone.siren.js b/src/backbone.siren.js index f4c0423..ae237f0 100644 --- a/src/backbone.siren.js +++ b/src/backbone.siren.js @@ -494,19 +494,26 @@ _.extend(BbSiren, { * * @param {Backbone.Siren.Store} store * @param {Backbone.Siren.Collection} collection + * @param {String} [representationToStore] limit which representation of the collection we want to store. + * Can be "current" or "self". */ - , addCollectionToStore: function (store, collection, storeCurrentOnly) { - var currentUrl = collection.link('current'); - if (currentUrl) { - store.addCollection(collection, 'current'); - } + , addCollectionToStore: function (store, collection, representationToStore) { + var currentUrl; // @todo, by having objects automatically added to the store on instantiation we end up having to pass // around store option. It feels a bit messy doing things this way. Consider re-visiting so that // objects no longer add themselves to the store on instantiation. - if (! storeCurrentOnly) { - store.addCollection(collection, 'self'); + if (representationToStore) { + store.addCollection(collection, representationToStore); + return; + } + + currentUrl = collection.link('current'); + if (currentUrl) { + store.addCollection(collection, 'current'); } + + store.addCollection(collection, 'self'); } @@ -567,31 +574,33 @@ _.extend(BbSiren, { , parseCollection: function (rawCollection, options) { options = options || {}; - var collection, currentUrl - , createNewCollectionFlag = true + var selfCollection, currentCollection, collection, currentUrl , store = options.store; if (store) { - collection = store.get(rawCollection); - if (collection) { - collection.update(rawCollection, options); - createNewCollectionFlag = false; - options.storeCurrentOnly = true; + selfCollection = store.get(rawCollection); + if (selfCollection) { + selfCollection.update(rawCollection, options); + } else { + options.representationToStore = 'self'; + selfCollection = new Backbone.Siren.Collection(rawCollection, options); } // Is it a "current" collection? currentUrl = getRawEntityUrl(rawCollection, 'current'); if (currentUrl) { - collection = store.get(currentUrl); - if (collection) { - collection.update(rawCollection, options); + currentCollection = store.get(currentUrl); + + if (currentCollection) { + currentCollection.update(rawCollection, options); } else { - createNewCollectionFlag = true; + options.representationToStore = 'current'; + currentCollection = new Backbone.Siren.Collection(rawCollection, options); } } - } - if (createNewCollectionFlag) { + collection = currentCollection || selfCollection; + } else { collection = new Backbone.Siren.Collection(rawCollection, options); } @@ -1160,7 +1169,7 @@ _.extend(BbSiren, { if (options.store) { this.siren.store = options.store; - BbSiren.addCollectionToStore(options.store, this, !!options.storeCurrentOnly); + BbSiren.addCollectionToStore(options.store, this, options.representationToStore); } if (options.ajaxOptions) { diff --git a/test/spec/backbone.siren.js b/test/spec/backbone.siren.js index 8a0ef3a..4f7b40f 100644 --- a/test/spec/backbone.siren.js +++ b/test/spec/backbone.siren.js @@ -195,13 +195,23 @@ describe('Backbone.Siren: ', function () { }); - it('does not add the "self" collection to the store if `storeCurrentOnly` is set to `true`', function () { + it('only adds the self collection to the store if `representationToStore` is set to `self`', function () { var currentCollection = new Backbone.Siren.Collection(rawCurrentCollection); var store = new Backbone.Siren.Store(); - Backbone.Siren.addCollectionToStore(store, currentCollection, true); - expect(store.get(currentCollection.link('self'))).not.toBeDefined(); + Backbone.Siren.addCollectionToStore(store, currentCollection, 'self'); + expect(store.get(currentCollection.link('self'))).toBeDefined(); + expect(store.get(currentCollection.link('current'))).not.toBeDefined(); + }); + + + it('only adds the current collection to the store if `representationToStore` is set to `collection`', function () { + var currentCollection = new Backbone.Siren.Collection(rawCurrentCollection); + var store = new Backbone.Siren.Store(); + + Backbone.Siren.addCollectionToStore(store, currentCollection, 'current'); expect(store.get(currentCollection.link('current'))).toBeDefined(); + expect(store.get(currentCollection.link('self'))).not.toBeDefined(); }); }); @@ -262,40 +272,39 @@ describe('Backbone.Siren: ', function () { it('updates an existing collection if it is already cached', function () { var store = new Backbone.Siren.Store(); - var collection = new Backbone.Siren.Collection(rawCollection, {store: store}); + var initialCollection = new Backbone.Siren.Collection(rawCollection, {store: store}); + var initialStoredCollection = store.get(initialCollection.url()); - // We tag the collection so that we know it's the same one (unlike models, collections don't have a "cid") - collection.tagged = true; - - collection = Backbone.Siren.parseCollection(rawCollection, {store: store}); + var updatedCollection = Backbone.Siren.parseCollection(rawCollection, {store: store}); + var updatedStoredCollection = store.get(updatedCollection.url()); - // Check the store - expect(store.get(getRawEntityUrl(rawCollection, 'self')).tagged).toBeTrue(); + // Check what's in the store + expect(updatedStoredCollection).toBe(initialStoredCollection); // Check the returned collection - expect(collection.tagged).toBeTrue(); + expect(updatedCollection).toBe(initialCollection); }); it('updates the "self" and "current" collections if they are both in the cache', function () { - var store = new Backbone.Siren.Store(); - var collection = new Backbone.Siren.Collection(rawCurrentCollection, {store: store}); - var collection2 = new Backbone.Siren.Collection(rawCurrentCollection2, {store: store}); + var store, collection, initialStoredSelfCollection, updatedStoredSelfCollection + , initialStoredCurrentCollection, updatedStoredCurrentCollection; - // We tag the collection so that we know it's the same one - collection.tagged = true; - collection2.tagged = true; + store = new Backbone.Siren.Store(); - // Update collection2 - collection2 = Backbone.Siren.parseCollection(rawCurrentCollection2, {store: store}); + // Create a current collection and a self collection + collection = new Backbone.Siren.Collection(rawCurrentCollection, {store: store}); - // Check the store - expect(store.get(getRawEntityUrl(rawCurrentCollection2, 'self')).tagged).toBeTrue(); - expect(store.get(getRawEntityUrl(rawCurrentCollection2, 'current')).tagged).toBeTrue(); + initialStoredSelfCollection = store.get(getRawEntityUrl(rawCurrentCollection, 'self')); + initialStoredCurrentCollection = store.get(getRawEntityUrl(rawCurrentCollection, 'current')); - // Check the returned collection - expect(collection.tagged).toBeTrue(); - expect(collection2.tagged).toBeTrue(); + Backbone.Siren.parseCollection(rawCurrentCollection); + + updatedStoredSelfCollection = store.get(getRawEntityUrl(rawCurrentCollection, 'self')); + updatedStoredCurrentCollection = store.get(getRawEntityUrl(rawCurrentCollection, 'current')); + + expect(updatedStoredSelfCollection).toBe(initialStoredSelfCollection); + expect(updatedStoredCurrentCollection).toBe(initialStoredCurrentCollection); }); From db9ff14cbde13fc2c7cd3af348116f9c435381a7 Mon Sep 17 00:00:00 2001 From: uglymunky Date: Tue, 17 Jun 2014 02:05:14 -0700 Subject: [PATCH 3/3] update models to the store --- src/backbone.siren.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backbone.siren.js b/src/backbone.siren.js index ae237f0..911382e 100644 --- a/src/backbone.siren.js +++ b/src/backbone.siren.js @@ -994,7 +994,7 @@ _.extend(BbSiren, { */ , update: function (rawModel, options) { if (BbSiren.isLoaded(rawModel)) { - this.set(this.parse(rawModel), options); + this.set(this.parse(rawModel, options), options); this.parseActions(); }