Search code examples
javascriptbackbone.jscoffeescript

Backbone.js: Collection containing multiple Models with same ID


I've a merged collection in Backbone which contains photos and albums.

To distinguish between them, i've added a field type which is either photo or album. When I populate the collection, I create different models within the Collection#model method

  model: (attrs, options) ->
    switch attrs.type
      when 'album' then new App.Models.Album(attrs, options)
      when 'photo' then new App.Models.Photo(attrs, options)

Now I've discoverd a strange bug where adding a photo and an album with the same ID (let's say 2) results in a merge.

I've tracked this down to these LOC in the source code. It seems that it's undoable without creating a fork of Backbone itself. I've tried it but it also fails 35 tests.

I thought of 4 different ways of doing this, I don't know which of them is the better one:

  1. I could add a prefix to the id. Let's say photo_2. This causes a change in the backend as well as some changes in the frontend to don't hit the server at /photos/photo_2
  2. I could fork Backbone and change these LOC.
  3. I could create two separate collections but have to deal with a merge and a sort in the view (which effects clients performance and requires a rewriting of the backend)
  4. I could start with a photo ID of, let's say 1000000. This would extremely decrease the probability that a given user which has uploaded a photo with a given ID has also created an album with the same ID.

Solution

  • Since version 1.2 you can use Collection.modelId to specify how your collection will uniquely identify models. In your case, you can do the following to ensure that your types have different IDs.

      var MyCollection = Backbone.Collection.extend({
        modelId: function (attrs) {
          return attrs.type + "-" + attrs.id;
        }
        // ...
      })