You do this to save your model:
@model.save null, success: -> ... error: -> ...
That null is the source of your problem, use {} and everything will start to behave better; if you combine your calls to @model.set and @model.save , everything will be even better:
attrs = subject: $("#js-subject").val()
A save call is as follows:
save model.save([attributes], [options])
[...]
The attribute attribute (as in set ) must contain the attributes that you would like to change
Thus, passing null for attributes means that you want to keep the model as it is.
When you save model, validation is basically saved until set , the code looks like this:
if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) { return false; }
Your attrs will be null , so set will not be called; however, if you allow save process your set , you will get the behavior you need. If you passed the wait: true parameter, save would have performed a manual validation on the passed attributes:
if (options.wait) { if (!this._validate(attrs, options)) return false; ... }
The _validate internal method is a wrapper for validate that does some bookkeeping and error handling. You are not using wait: true , so this does not apply to you, but I thought it was worth mentioning anyway.
Consider a simple example with a model whose validate always fails. If you say this:
@model.on 'error', @error @model.save attrs, success: -> console.log 'AJAX success' error: -> console.log 'AJAX error'
then @error will be @error because save will eventually call set with some attributes and set will call validate . Demo: http://jsfiddle.net/ambiguous/HHQ2N/1/
But if you say:
@model.save null, ...
null will skip the set call . Demo: http://jsfiddle.net/ambiguous/6pX2e/ (here AJAX will fail).
Your call to @model.set before @model.save should start your error handler, but if you don't check what @model.set , execution will blindly continue until you call save and talk to your server.
So you have three things:
- You do not invoke
save as it should be. - You ignore the return value of
@model.set and lose the chance to catch validation errors. - Handling database arguments for
save(null, ...) might be better, but I don't know if it's worth trying to handle the weird way of calling it.
You should combine your set / save pair only in save or check what set returns.