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?
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With