Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js using non-restful actions on a restful model

I have a regular restful model that I do get, create, delete and update. On top of that, I'd like to call special actions on that model, like change_password.

The regular RESTful routes are traditional Rails 3 routes:

fetch   => GET    /api/models/:id
save    => PUT    /api/models/:id
create  => POST   /api/models
destroy => DELETE /api/models/:id

But, on top of those, I have special operations:

changePassword => GET /api/models/:id/change_password
activate       => GET /api/models/:id/activate

And so on.

What do I need to setup on the model, so it recognizes those new actions, and how to wrap the calls into model methods?

like image 735
kolrie Avatar asked Feb 22 '12 19:02

kolrie


2 Answers

It's fairly simple to add new methods to a Model - just specify the new methods in .extend(). You have to code some of this yourself, but you can take advantage of existing machinery like Backbone.sync (mostly just a wrapper around $.ajax()) and the Model's existing url property:

var MyModel = Backbone.Model.extend({

    activate: function(opts) {
        var model = this,
            url = model.url() + '/activate',
            // note that these are just $.ajax() options
            options = {
                url: url,
                type: 'POST' // see my note below
            };

        // add any additional options, e.g. a "success" callback or data
        _.extend(options, opts);

        return (this.sync || Backbone.sync).call(this, null, this, options);
    },

    // etc

});

Just as a comment, from a REST perspective, your changePassword and activate operations should not be GET methods - all GET methods should be idempotent. This is not just RESTifarianism, it's a Good Idea - you could end up caching these URLs (so nothing happens) or hitting them multiple times by accident (usually requiring user confirmation with a POST request). Make these POST calls if you can.

like image 77
nrabinowitz Avatar answered Sep 20 '22 14:09

nrabinowitz


I would advise that if possible add a Password model/controller where you can call save on to change the password. This follows the REST standards and is built in functionality of Backbone.js

If that's not an option, the following is a CoffeeScript example, add this to your model:

activate: ->
  unless user.get('active')
    (@sync || Backbone.sync).call @, 'activate', @,
      url: "#{@url()}/users/#{message.get('id')}/activate"
      data: {}
      complete: =>
        user.set(active: true)
        @set(active: true)
like image 29
brupm Avatar answered Sep 18 '22 14:09

brupm