26

If I have a model named "Book" and a collection named "Library" defined as below:

Book

app.Book = Backbone.Model.extend({
    defaults: {
        title: 'No title',
        author: 'Unknown'
    }
});

Library

app.Library = Backbone.Collection.extend({
    model: app.Book,
    url: '/api/books'
});

When I call BookInstance.save() how does it come up with the URL to use? Does it derive it from the collection?

In Backbone.model there are 2 options: url and urlRoot. What is the purpose and difference between these?

In Backbone.collection, there is a single parameter url. Is this always the GET request for the RESTFUL api?

Chris Muench
  • 17,444
  • 70
  • 209
  • 362

2 Answers2

36

Basically, there are 3 possibilities to construct a model's url:

  • If the model object exists in a collection then its url method will return an address composed of the collection.url and model.id: [collection.url]/[id].

  • If you don't want to use a model inside the collection, then model.urlRoot's value can be used instead of the collection.url fragment, resulting in the following pattern: [urlRoot]/[id].

  • Finally, if you're NOT planning to persist more that one model of a given type to the server or will be defining URLs for each model upon their creation, you can directly assign a value to model.url.

Collections send only GET requests — to get an array of models' JSON data. For saving, removing, and updating, the individual model's save() (POST/PUT/PATCH) and destroy() (DELETE) methods are used.

Here's the source code of Backbone.Model.url, which should help you:

url: function() {
  var base =
    _.result(this, 'urlRoot') ||
    _.result(this.collection, 'url') ||
    urlError();
  if (this.isNew()) return base;
  var id = this.get(this.idAttribute);
  return base.replace(/[^\/]$/, '$&/') + encodeURIComponent(id);
}
russt
  • 1,548
  • 2
  • 14
  • 16
mirrormx
  • 4,049
  • 1
  • 19
  • 17
  • Does a backbone.model which is inside a collection use the Backbone.Collection.url property to determine the url to save, update, or remove? – Chris Muench May 31 '13 at 16:59
  • It uses it for every operation. – mirrormx May 31 '13 at 17:16
  • check out [this](http://stackoverflow.com/questions/17461264/backbonejs-model-url-using-collection-url). you can overwrite url settings i.e yourModel.save({ url: yourModel.urlRoot + yourModel.get("id") }); – oak Nov 21 '13 at 20:56
  • @mirrormx hey in the url function initially it is checking for urlroort of model then url of collection where is it checking for the url of model? – StateLess Feb 12 '15 at 05:18
12

In model

  1. urlRoot is used for the Model.
  2. url is used for the instance of the Model.

So if urlRoot exists then book.fetch() will fetch the data given id, for example

var Book = Backbone.Model.extend({urlRoot: 'books' });
var book = new Book({id: 1});
book.fetch();  // will get /books/1

var Book = Backbone.Model.extend({});
var book = new Book({url: 'books/1'});
book.fetch();  // will get /books/1


var Books = Backbone.Collection.extend({model: Book});
var books = new Books({ /*....*/ });
books.fetch(); // will get /books/ 

You can refer the backbone Model urlRoot source code here

I hope it makes sense to you, good luck.

Alan Dong
  • 3,981
  • 38
  • 35