I have a Backbone model:
var User = Backbone.Model.extend({
idAttribute: '_id',
url: '/api/user',
defaults:
{ username: ''
}
});
I fetch it:
var user = new User();
user.fetch();
Now, as an click
event in one of my views, I have this:
toggleSubscription: function () {
user.set('subscriptions', true);
user.save();
}
This causes a POST request. However, the record already exists on the server, and since I fetched it (and the model instance has an id
property), I thought that Backbone should do a PUT instead of a POST. Why might it be doing a POST instead?
Try checking
user.isNew()
.Looks like you created a new model which does not have an ID, that's why it's trying to add it during
Backbone.sync
.UPDATE:
Above is exactly true. It does
POST
because it's a new model (which means, it does not have an id). Before you fetch a model, you need to give it an id. In your example:It may be worth checking if maybe
emulateHTTP
is true. This will change all your PUT into POST with an added_method
header (you may also want to check that this exists to confirm the idea).if the model does not yet have an id, it is considered to be new... AND therefore backbone will do a
PUT
request rather than aPOST
.This behavior can be overridden simply by adding
type: 'POST'
to your save block:The server response must be in this way:
Because you set _id as the primary key. When model is fetched verify the value of _id it must have a value: console.log( model.get('_id') );
My thought is that you set in your backbone model '_id' as primary key, but service is returning you 'id'
Update: Adding sample code of normal behavior:
Output: PUT /api/user 405 (Method Not Allowed) POST /api/user 404 (Not Found)
Check how the first instance of the Model has an id and it tries to do the PUT but the other POST. I cannot reproduce your issue, so my thought is that the problem is on your server response.
Use urlRoot property to set base URL
/api/user
. Then/api/user
when you save a model which doesn't have_id
property set and/api/user/{_id}
when you save a model which has_id
property set. Notice that it automatically appends_id
value to the base URL.It will look for value of
_id
property because you have set that value toidAttribute
.