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:
- 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
- I could fork Backbone and change these LOC.
- 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)
- 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.
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:
- 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
- I could fork Backbone and change these LOC.
- 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)
- 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.
3 Answers
Reset to default 7Since 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;
}
// ...
})
I would suggest that on both Album and Photo, you add the following:
idAttribute: 'uniqueId'
parse: function(response) {
response.uniqueId = type+'_'+response.id
return response;
}
idAttribute:'uniqueId'
if this uniqueId is not known while declaring, try
idAttribute:'UUID'
I generated one from https://www.uuidgenerator/ and put it here, this attribute defined here need not be in model, so I just put in a UUID.