aherrick
aherrick

Reputation: 20161

Backbone JS Handle Save Model?

Using Backbone I can fetch the Collection like below and render a Backbone View for each record:

Person = Backbone.Model.extend({});

var PersonCollection = Backbone.Collection.extend({

    model: Person,
    url: '/home/people/'
});

When I spin up a new person using Backbone like below, isn't it supposed to already handle the .save() functionality by posting to the URL defined in the above collection?

var p = new Person({ Name: 'Andrew', Age: 24 });
p.save();
// Uncaught Error: A 'url' property or function must be specified
// I thought it was supposed to use the Collection's URL?
// I can get around this by explicitly setting p.URL but doesn't seem right

Upvotes: 3

Views: 9121

Answers (3)

Raynos
Raynos

Reputation: 169373

You can just set the collection

Person.collection = PersonCollection

Now it will magically know the url.

Upvotes: 6

aherrick
aherrick

Reputation: 20161

Looks like an approach is to use the current collection and create which handles adding it to the collection and saving it

this.people.create(p);

The source is below. Create is off the collection, so it sets the Models collection to this Then once the Save it success it adds Model to your collection. So it passes the model to getUrl, the getUrl looks at the URL property on the model, which in turn passes the collection to getUrl again... that way we don't have to redefine URL...

create : function(model, options) {
  var coll = this;
  options || (options = {});
  if (!(model instanceof Backbone.Model)) {
    model = new this.model(model, {collection: coll});
  } else {
    model.collection = coll;
  }
  var success = function(nextModel, resp) {
    coll.add(nextModel);
    if (options.success) options.success(nextModel, resp);
  };
  return model.save(null, {success : success, error : options.error});
},

Upvotes: 7

Bill Eisenhauer
Bill Eisenhauer

Reputation: 6183

According to the backbone.js code in Backbone.sync, this does not seem like the case. Perhaps the documentation is old or not correct. The code reads:

// Helper function to get a URL from a Model or Collection as a property
// or as a function.
var getUrl = function(object) {
  if (!(object && object.url)) throw new Error("A 'url' property or function must be specified");
  return _.isFunction(object.url) ? object.url() : object.url;
};

which suggests to me that the model needs its own url. So you should just do this:

Person = Backbone.Model.extend({
  url: function() {
    if (this.isNew()) return '/home/people/';
    return '/home/whatever-this-route-would-be';
  }
});

Upvotes: 5

Related Questions