Reputation: 592
I'm trying to override Backbone.sync in order to set the "id" attribute every time we fetch a model. This way, I am sure the next model.save() will fire an update and not a create, even if the fetch() didn't respond with an id.
Backbone._sync = Backbone.sync;
Backbone.sync = function(method, model, options) {
var params = _.clone(options);
params.success = function(model) {
if(method == 'read' && model.isNew()) {
var id = Math.floor(Math.random()*1000);
model.set({ "id": id });
}
if(options.success) options.success(model);
};
Backbone._sync(method, model, params);
}
But the model passed to the success function seems not to be a Backbone model, but just an object. So I can't use any method (like model.isNew()) on it. Any idea of what I did wrong?
Upvotes: 2
Views: 6588
Reputation: 7540
@nrabinowitz
Just to add tiny more amount of clarity to this. I am using RedbeanPHP which has inbuilt JSON support. One issue is that when you create an object, it returns the new id of that object in the result tag, and you need this for the new object if you want to edit it.
// My model object is a User. (we are all Users in some way).
var User = Backbone.Model.extend(
{
url : "/user/rpc",
defaults: {
email: "email",
password: "",
admin: 0
},parse: function(resp, xhr) {
// check if the model is new, if so, set the id of this model for future requests so RedBean knows the id of this object.
if(this.new()){
this.set({"id":resp.result});
console.log(this);
}
}
}
);
Upvotes: 1
Reputation: 55688
It sounds like you might want to override Model.fetch
or Model.parse
instead of Backbone.sync
. Backbone.sync
just takes $.ajax()
options, so the success
callback is just receiving the JSON response from the server, not an instantiated model.
The default Model.fetch()
callback looks like this:
options.success = function(resp, status, xhr) {
if (!model.set(model.parse(resp, xhr), options)) return false;
if (success) success(model, resp);
};
Here model
refers to the current instance, as you intend. So you might consider overriding Model.fetch
to add an id if it's not there, or, probably better, overriding model.parse()
, which is a passthrough by default and is intended as a hook for you to munge the server data. I'm not thrilled with your random number id implementation, as there's still a chance of collisions, especially if you're making a lot of models - you might try using model.cid
(guaranteed to be unique in the client, though it might have collisions with server-provided IDs) or Underscore's _.uniqueId():
parse: function(resp, xhr) {
if (this.isNew() && !resp.id) {
resp.id = _.uniqueId('model-');
}
}
Upvotes: 7