Merge branch 'http' of github.com:NiKnight/jugglingdb

This commit is contained in:
Anatoliy Chakkaev 2013-03-31 14:08:38 +04:00
commit 76c7fbd6ec
3 changed files with 62 additions and 12 deletions

View File

@ -24,15 +24,15 @@ Called before and after validations.
Called before and after destroy on instance. Called before and after destroy on instance.
Each hook except `initialize` accepts callback as first argument. This callback Each hook except `initialize` accepts callback as the first argument. This callback
should be called when hook done. All hooks called on object instance, but it's should be called when hook is done. All hooks are called on object instance, but it's
not recommended to use `this` for updating in all hooks where data argument not recommended to use `this` for updating all hooks where data argument is
available (second argument for all data-related before-hooks: save, update, available (second argument for all data-related before-hooks: save, update,
create). create).
## INITIALIZE ## INITIALIZE
Initialize hook called when new object created after all setters and default Initialize hook called when new object created after all setters and defaults
being applied. being applied.
Model.afterInitialize = function() { Model.afterInitialize = function() {
@ -43,7 +43,7 @@ being applied.
## CREATE ## CREATE
Create hooks called when object created. Create hooks is being called when object is created.
The `beforeCreate` hook accepts `data` as a second argument. The `beforeCreate` hook accepts `data` as a second argument.
Model.beforeCreate = function(next, data) { Model.beforeCreate = function(next, data) {
@ -74,7 +74,7 @@ Example output will be:
Update hooks called on each save except create. Update hooks called on each save except create.
The `beforeUpdate` hook accepts data as second argument. The `beforeUpdate` hook accepts data as second argument.
Data argument only containing actual data for update, not full object data. The data argument contains only actual data for update, not full object data.
Model.beforeUpdate = function(next, data) { Model.beforeUpdate = function(next, data) {
// use data argument to update object // use data argument to update object
@ -103,9 +103,8 @@ Example output will be:
## SAVE ## SAVE
Save hooks called on each save, both update and create. Save hooks called on each save, both during update and create.
The `beforeSave` hook accepts `data` as a second argument. The `beforeSave` hook accepts `data` as a second argument. For this cook hook `data` argument is the same as `this` when model.save() is called. When model.updateAttributes() called data argument contains only actual changes.
For `beforeSave` hook `data` argument is the same as `this`.
Model.beforeSave = function(next, data) { Model.beforeSave = function(next, data) {
if ('string' !== typeof data.tags) { if ('string' !== typeof data.tags) {
@ -120,12 +119,12 @@ For `beforeSave` hook `data` argument is the same as `this`.
## DESTROY ## DESTROY
Destroy hooks called when `model.destroy()` called. Please note that Hook is destroyed once `model.destroy()` is called. Please note that
`destroyAll` method doesn't call destroy hooks. `destroyAll` method doesn't call destroy hooks.
## VALIDATE ## VALIDATE
Validate hooks callen before and after validation and should be used for data Validate hooks called before and after validation and should be used for data
modification and not for validation. Use custom validation described in modification and not for validation. Use custom validation described in
jugglingdb-validations(3) man section. jugglingdb-validations(3) man section.

View File

@ -751,8 +751,12 @@ AbstractClass.prototype.destroy = function (cb) {
this.trigger('destroy', function (destroyed) { this.trigger('destroy', function (destroyed) {
this._adapter().destroy(this.constructor.modelName, this.id, function (err) { this._adapter().destroy(this.constructor.modelName, this.id, function (err) {
if (err) {
return cb(err);
}
destroyed(function () { destroyed(function () {
if(cb) cb(err); if(cb) cb();
}); });
}.bind(this)); }.bind(this));
}); });

View File

@ -72,6 +72,20 @@ describe('hooks', function() {
(new User).save(); (new User).save();
}); });
it('afterCreate should not be triggered on failed create', function(done) {
var old = User.schema.adapter.create;
User.schema.adapter.create = function(modelName, id, cb) {
cb(new Error('error'));
}
User.afterCreate = function() {
throw new Error('shouldn\'t be called')
};
User.create(function (err, user) {
User.schema.adapter.create = old;
done();
});
});
}); });
describe('save', function() { describe('save', function() {
@ -202,6 +216,23 @@ describe('hooks', function() {
user.updateAttributes({name: 1, email: 2}); user.updateAttributes({name: 1, email: 2});
}); });
}); });
it('afterUpdate should not be triggered on failed save', function(done) {
User.afterUpdate = function() {
throw new Error('shouldn\'t be called')
};
User.create(function (err, user) {
var old = User.schema.adapter.save;
User.schema.adapter.save = function(modelName, id, cb) {
cb(new Error('error'));
}
user.save(function(err) {
User.schema.adapter.save = old;
done();
});
});
});
}); });
describe('destroy', function() { describe('destroy', function() {
@ -221,6 +252,22 @@ describe('hooks', function() {
user.destroy(); user.destroy();
}); });
}); });
it('afterDestroy should not be triggered on failed destroy', function(done) {
var old = User.schema.adapter.destroy;
User.schema.adapter.destroy = function(modelName, id, cb) {
cb(new Error('error'));
}
User.afterDestroy = function() {
throw new Error('shouldn\'t be called')
};
User.create(function (err, user) {
user.destroy(function(err) {
User.schema.adapter.destroy = old;
done();
});
});
});
}); });
describe('lifecycle', function() { describe('lifecycle', function() {