Backbone.js Model different url for create and update?

20,197

Solution 1

Methods .fetch(), .save() and .destroy() on Backbone.Model are checking if the model has .sync() defined and if yes it will get called otherwise Backbone.sync() will get called (see the last lines of the linked source code).

So one of the solutions is to implement .sync() method.

Example:

var User = Backbone.Model.extend({

  // ...

  methodToURL: {
    'read': '/user/get',
    'create': '/user/create',
    'update': '/user/update',
    'delete': '/user/remove'
  },

  sync: function(method, model, options) {
    options = options || {};
    options.url = model.methodToURL[method.toLowerCase()];

    return Backbone.sync.apply(this, arguments);
  }
}

Solution 2

To abstract dzejkej's solution one level further, you might wrap the Backbone.sync function to query the model for method-specific URLs.

function setDefaultUrlOptionByMethod(syncFunc)
    return function sync (method, model, options) {
        options = options  || {};
        if (!options.url)
            options.url = _.result(model, method + 'Url'); // Let Backbone.sync handle model.url fallback value
        return syncFunc.call(this, method, model, options);
    }
}

Then you could define the model with:

var User = Backbone.Model.extend({
    sync: setDefaultUrlOptionByMethod(Backbone.sync),
    readUrl: '/user/get',
    createUrl: '/user/create',
    updateUrl: '/user/update',
    deleteUrl: '/user/delete'
});

Solution 3

Are you dealing with a REST implementation that isn't to spec or needs some kind of workaround?

Instead, consider using the emulateHTTP option found here:

http://documentcloud.github.com/backbone/#Sync

Otherwise, you'll probably just need to override the default Backbone.sync method and you'll be good to go if you want to get real crazy with that... but I don't suggest that. It'd be best to just use a true RESTful interface.

Share:
20,197
panosru
Author by

panosru

A competent professional, proficient in Greek, English and Russian languages, with the ability to combine multiple areas of expertise to deliver projects from concept to completion. Business administrator with 7 years of experience, 5 years as a cryptocurrency trader, 10 years as an educator and 20 years as an IT professional.

Updated on October 09, 2020

Comments

  • panosru
    panosru over 3 years

    lets say I have a Backbone Model and I create an instance of a model like this:

    var User = Backbone.Model.extend({ ... });
    var John = new User({ name : 'John', age : 33 });
    

    I wonder if it is possible when I use John.save() to target /user/create when I use John.save() on second time (update/PUT) to target /user/update when I use John.fetch() to target /user/get and when I use John.remove() to target /user/remove

    I know that I could define John.url each time before I trigger any method but I'm wondering if it could be happen automatically some how without overriding any Backbone method.

    I know that I could use one url like /user/handle and handle the request based on request method (GET/POST/PUT/DELETE) but I'm just wondering if there is a way to have different url per action in Backbone.

    Thanks!