blob: 69a4d56554bbf3a55e8f956deef3c96f55afed0b [file] [log] [blame]
Scott Bakerb7aba682014-07-07 21:30:52 -07001/**
2 * Backbone-tastypie.js 0.1
3 * (c) 2011 Paul Uithol
4 *
5 * Backbone-tastypie may be freely distributed under the MIT license.
6 * Add or override Backbone.js functionality, for compatibility with django-tastypie.
7 */
8(function( undefined ) {
9 var Backbone = this.Backbone;
10
11 /**
12 * Override Backbone's sync function, to do a GET upon receiving a HTTP CREATED.
13 * This requires 2 requests to do a create, so you may want to use some other method in production.
14 * Modified from http://joshbohde.com/blog/backbonejs-and-django
15 */
16 Backbone.oldSync = Backbone.sync;
17 Backbone.sync = function( method, model, options ) {
18 if ( method === 'create' ) {
19 var dfd = new $.Deferred();
20
21 // Set up 'success' handling
22 dfd.done( options.success );
23 options.success = function( resp, status, xhr ) {
24 // If create is successful but doesn't return a response, fire an extra GET.
25 // Otherwise, resolve the deferred (which triggers the original 'success' callbacks).
26 if ( xhr.status === 201 && !resp ) { // 201 CREATED; response null or empty.
27 var location = xhr.getResponseHeader( 'Location' );
28 return $.ajax( {
29 url: location,
30 success: dfd.resolve,
31 error: dfd.reject
32 });
33 }
34 else {
35 return dfd.resolveWith( options.context || options, [ resp, status, xhr ] );
36 }
37 };
38
39 // Set up 'error' handling
40 dfd.fail( options.error );
41 options.error = dfd.reject;
42
43 // Make the request, make it accessibly by assigning it to the 'request' property on the deferred
44 dfd.request = Backbone.oldSync( method, model, options );
45 return dfd;
46 }
47
48 return Backbone.oldSync( method, model, options );
49 };
50
51 Backbone.Model.prototype.idAttribute = 'resource_uri';
52
53 Backbone.Model.prototype.url = function() {
54 // Use the id if possible
55 var url = this.id;
56
57 // If there's no idAttribute, try to have the collection construct a url. Fallback to 'urlRoot'.
58 if ( !url ) {
59 url = this.collection && ( _.isFunction( this.collection.url ) ? this.collection.url() : this.collection.url );
60 url = url || this.urlRoot;
61 }
62
63 url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
64
65 return url;
66 };
67
68 /**
69 * Return 'data.objects' if it exists and is an array, or else just plain 'data'.
70 */
71 Backbone.Model.prototype.parse = function( data ) {
72 return data && data.objects && ( _.isArray( data.objects ) ? data.objects[ 0 ] : data.objects ) || data;
73 };
74
75 Backbone.Collection.prototype.parse = function( data ) {
76 return data && data.objects;
77 };
78
79 Backbone.Collection.prototype.url = function( models ) {
80 var url = this.urlRoot || ( models && models.length && models[0].urlRoot );
81 url && ( url += ( url.length > 0 && url.charAt( url.length - 1 ) === '/' ) ? '' : '/' );
82
83 // Build a url to retrieve a set of models. This assume the last part of each model's idAttribute
84 // (set to 'resource_uri') contains the model's id.
85 if ( models && models.length ) {
86 var ids = _.map( models, function( model ) {
87 var parts = _.compact( model.id.split('/') );
88 return parts[ parts.length - 1 ];
89 });
90 url += 'set/' + ids.join(';') + '/';
91 }
92
93 return url;
94 };
95})();