The trunk performs a POST instead of a PUT during updates when a composite key is used

I use a composite key in my model and generate an ID based on my composite key:

app.Assignment = Backbone.Model.extend({ idAttribute : [ 'personId', 'jobId' ], parse : function(resp) { resp.id = resp.personId + "_" + resp.jobId; return resp; } }); 

but Backbone still believes that all instances of Assignment are new, although I set an id in the analysis method when you retrieve them from the API. As a result, Backbone does not DELETE and performs POST instead of PUT during updates. How can I get around this or what is the “right way” for this?

Update:

It seems like replacing resp.id with this.id solves the problem.

+7
source share
3 answers

The results of the parse method of the Backbone.Model method are passed to the set method, which sets the attributes of the model. The point of the confusion for you, I think, is that the model identifier is not one of its attributes; This is one of its properties.

So what happens is:

  • Your original data is returned from the server and passed to parse
  • The same source data, supplemented by the id attribute, is passed to set
  • set looks like your idAttribute ( [ 'personId', 'jobId' ] ) and all the keys in the source data
  • Since none of these keys matches idAttribute , none of them are used as the model identifier, and therefore you get your problem.

Your solution to setting this.id inside parse works, but it may cause problems in the future, because the parsing is usually designed to work with it (source data), and not to change the model itself; this part should happen next when set is called. Instead, a cleaner solution would be to do something like the following:

 app.Assignment = Backbone.Model.extend({ // note that no idAttribute is specified, leaving it as the default "id" parse : function(resp) { resp.id = resp.personId + "_" + resp.jobId; return resp; } } 

Or if you need another id ...

 app.Assignment = Backbone.Model.extend({ idAttribute: 'personAndJobId', parse : function(resp) { resp.personAndJobId = resp.personId + "_" + resp.jobId; return resp; } } 
+2
source

Besides the problems with idAttribute here, you can always force Backbone to use a specific HTTP method using type parameters passed to save() .

model.save(null, { type: 'put' })

0
source

I have never worked with a composite ID in Backbone, but I think this may be an easy answer to your problem:

 initialize: function() { this.set("id", this.generateID()); }, generateID = function () { return this.personId + + "_" + this.jobId; } 

Using this code in the definition of the baseline model, you create a unique identifier for each model, and you should not have problems updating and saving it (and you do not need to set any idAttribute).

0
source

All Articles