Skip to content

Commit

Permalink
adding Backbone.emulateHttp for frameworks that don't support HTTP. I…
Browse files Browse the repository at this point in the history
…ssue #11
  • Loading branch information
jashkenas committed Oct 17, 2010
2 parents 6899988 + 1966269 commit 7721f84
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 1 deletion.
15 changes: 14 additions & 1 deletion backbone.js
Expand Up @@ -27,6 +27,10 @@
// For Backbone's purposes, jQuery owns the `$` variable.
var $ = this.jQuery;

// Turn on `emulateHttp` to fake `"PUT"` and `"DELETE"` requests via
// the `_method` parameter.
Backbone.emulateHttp = false;

// Backbone.Events
// -----------------

Expand Down Expand Up @@ -602,12 +606,21 @@
// * Send up the models as XML instead of JSON.
// * Persist models via WebSockets instead of Ajax.
//
// Turn on `Backbone.emulateHttp` in order to send `PUT` and `DELETE` requests
// as `POST`, with an `_method` parameter containing the true HTTP method.
// Useful when interfacing with server-side languages like **PHP** that make
// it difficult to read the body of `PUT` requests.
Backbone.sync = function(method, model, success, error) {
var sendModel = method === 'create' || method === 'update';
var data = sendModel ? {model : JSON.stringify(model)} : {};
var type = methodMap[method];
if (Backbone.emulateHttp && (type === 'PUT' || type === 'DELETE')) {
data._method = type;
type = 'POST';
}
$.ajax({
url : getUrl(model),
type : methodMap[method],
type : type,
data : data,
dataType : 'json',
success : success,
Expand Down
2 changes: 2 additions & 0 deletions test/model.js
Expand Up @@ -5,6 +5,8 @@ $(document).ready(function() {
// Variable to catch the last request.
window.lastRequest = null;

window.originalSync = Backbone.sync;

// Stub out Backbone.request...
Backbone.sync = function() {
lastRequest = _.toArray(arguments);
Expand Down
87 changes: 87 additions & 0 deletions test/sync.js
@@ -0,0 +1,87 @@
$(document).ready(function() {

module("Backbone.sync");

// Variable to catch the last request.
window.lastRequest = null;

// Stub out jQuery.ajax...
$.ajax = function(obj) {
lastRequest = obj;
};

var Library = Backbone.Collection.extend({
url : function() { return '/library'; }
});

var library = new Library();

var attrs = {
title : "The Tempest",
author : "Bill Shakespeare",
length : 123
};

test("sync: read", function() {
Backbone.sync = originalSync;
library.fetch();
equals(lastRequest.url, '/library');
equals(lastRequest.type, 'GET');
equals(lastRequest.dataType, 'json');
ok(_.isEmpty(lastRequest.data));
});

test("sync: create", function() {
library.add(library.create(attrs));
equals(lastRequest.url, '/library');
equals(lastRequest.type, 'POST');
equals(lastRequest.dataType, 'json');
var data = JSON.parse(lastRequest.data.model);
equals(data.title, 'The Tempest');
equals(data.author, 'Bill Shakespeare');
equals(data.length, 123);
});

test("sync: update", function() {
library.first().save({id: '1-the-tempest', author: 'William Shakespeare'});
equals(lastRequest.url, '/library/1-the-tempest');
equals(lastRequest.type, 'PUT');
equals(lastRequest.dataType, 'json');
var data = JSON.parse(lastRequest.data.model);
equals(data.id, '1-the-tempest');
equals(data.title, 'The Tempest');
equals(data.author, 'William Shakespeare');
equals(data.length, 123);
});

test("sync: update with emulateHttp", function() {
Backbone.emulateHttp = true;
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
equals(lastRequest.url, '/library/2-the-tempest');
equals(lastRequest.type, 'POST');
equals(lastRequest.dataType, 'json');
equals(lastRequest.data._method, 'PUT');
var data = JSON.parse(lastRequest.data.model);
equals(data.id, '2-the-tempest');
equals(data.title, 'The Tempest');
equals(data.author, 'Tim Shakespeare');
equals(data.length, 123);
});

test("sync: destroy", function() {
Backbone.emulateHttp = false;
library.first().destroy();
equals(lastRequest.url, '/library/2-the-tempest');
equals(lastRequest.type, 'DELETE');
ok(_.isEmpty(lastRequest.data));
});

test("sync: destroy with emulateHttp", function() {
Backbone.emulateHttp = true;
library.first().destroy();
equals(lastRequest.url, '/library/2-the-tempest');
equals(lastRequest.type, 'POST');
equals(JSON.stringify(lastRequest.data), '{"_method":"DELETE"}');
});

});
1 change: 1 addition & 0 deletions test/test.html
Expand Up @@ -13,6 +13,7 @@
<script type="text/javascript" src="model.js"></script>
<script type="text/javascript" src="collection.js"></script>
<script type="text/javascript" src="view.js"></script>
<script type="text/javascript" src="sync.js"></script>
<script type="text/javascript" src="speed.js"></script>
</head>
<body>
Expand Down

0 comments on commit 7721f84

Please sign in to comment.