Q:

How to use Backbone.Model.save() promise with validation

I'm trying to use the promise returned from Backbone.model.save().  Actually, per spec, it returns a promise if valid and false if not.  I'd like to use the return value, regardless of the type, in future deferred.done() and deferred.fail() calls.  Like this:
var promise = model.save();

$.when(promise).done(function() {
   console.log('success!');
});

$.when(promise).fail(function() {
   console.log('dang');
});

But, $.when() when passed a non-promise fires, done(), so, in the above, if the model is invalid, $.when(false).done() fires, and you get "success!".
I know I can use the success and error attributes in save(), but with my code, it's advantageous to have multiple done() functions applied later.  That's the power of the promise afterall.
So, I'm left with:
var promise = model.save();

if (promise) {
    $.when(promise).done(function() {
        console.log('success!');
    });

    $.when(promise).fail(function() {
        console.log('dang');
    });
} else {
    console.log('dang');
}

I hate not being DRY.
var promise = model.save();

var fail = function() {
    console.log('dang');
};

if (promise) {
    $.when(promise).done(function() {
        console.log('success!');
    });

    $.when(promise).fail(function() {
        fail();
    });
} else {
    fail();
}

Geting pretty messy.  You get the picture.  I'm hoping I'm just missing something here.

A:

You can override Backbone.save method to have your desired behavior. If the returned value from the original save function is a boolean (which means validation failed), just return a custom promise and reject its related deferred. 
var oldSaveFunction = Backbone.Model.prototype.save;
Backbone.Model.prototype.save = function(){
    var returnedValue = oldSaveFunction.apply(this, arguments),
        deferred = new $.Deferred();

    if(_.isBoolean(returnedValue)){
        deferred.reject();
        return deferred.promise();
    }

    return returnedValue;
}

var Person = Backbone.Model.extend({
    url : 'http://www.google.com',
    validate : function(attributes){
         if(!("name" in attributes))
             return "invalid";
    }
});

var person = new Person();
$.when(person.save()).fail(function(){
   console.log("failed"); 
});

Try it on this fiddle
http://jsfiddle.net/WNHXz/1/

