mirror of https://gitee.com/bigwinds/arangodb
commit
c0a02f9f8a
|
@ -55,6 +55,47 @@ person.attributes // => { name: "Pete", admin: true, active: true }
|
||||||
person.errors // => {admin: [ValidationError: value is not allowed]}
|
person.errors // => {admin: [ValidationError: value is not allowed]}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The following events are emitted by a model:
|
||||||
|
|
||||||
|
- beforeCreate
|
||||||
|
- afterCreate
|
||||||
|
- beforeSave
|
||||||
|
- afterSave
|
||||||
|
- beforeUpdate
|
||||||
|
- afterUpdate
|
||||||
|
- beforeRemove
|
||||||
|
- afterRemove
|
||||||
|
|
||||||
|
Model lifecycle:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var person = new PersonModel();
|
||||||
|
person.on('beforeCreate', function() {
|
||||||
|
var model = this;
|
||||||
|
model.fancyMethod(); // Do something fancy with the model
|
||||||
|
});
|
||||||
|
var people = new Repository(appContext.collection("people"), { model: PersonModel });
|
||||||
|
|
||||||
|
people.save(person);
|
||||||
|
// beforeCreate()
|
||||||
|
// beforeSave()
|
||||||
|
// The model is created at db
|
||||||
|
// afterSave()
|
||||||
|
// afterCreate()
|
||||||
|
|
||||||
|
people.update(person, data);
|
||||||
|
// beforeUpdate(data)
|
||||||
|
// beforeSave(data)
|
||||||
|
// The model is updated at db
|
||||||
|
// afterSave(data)
|
||||||
|
// afterUpdate(data)
|
||||||
|
|
||||||
|
people.remove(person);
|
||||||
|
// beforeRemove()
|
||||||
|
// The model is deleted at db
|
||||||
|
// afterRemove()
|
||||||
|
```
|
||||||
|
|
||||||
!SUBSECTION Extend
|
!SUBSECTION Extend
|
||||||
<!-- js/server/modules/org/arangodb/foxx/model.js -->
|
<!-- js/server/modules/org/arangodb/foxx/model.js -->
|
||||||
@startDocuBlock JSF_foxx_model_extend
|
@startDocuBlock JSF_foxx_model_extend
|
||||||
|
|
|
@ -32,6 +32,8 @@ var Model,
|
||||||
joi = require("joi"),
|
joi = require("joi"),
|
||||||
is = require("org/arangodb/is"),
|
is = require("org/arangodb/is"),
|
||||||
extend = require('org/arangodb/extend').extend,
|
extend = require('org/arangodb/extend').extend,
|
||||||
|
EventEmitter = require('events').EventEmitter,
|
||||||
|
util = require('util'),
|
||||||
excludeExtraAttributes,
|
excludeExtraAttributes,
|
||||||
metadataSchema = {
|
metadataSchema = {
|
||||||
_id: joi.string().optional(),
|
_id: joi.string().optional(),
|
||||||
|
@ -142,8 +144,11 @@ Model = function (attributes) {
|
||||||
} else if (attributes) {
|
} else if (attributes) {
|
||||||
instance.attributes = _.clone(attributes);
|
instance.attributes = _.clone(attributes);
|
||||||
}
|
}
|
||||||
|
EventEmitter.call(instance);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
util.inherits(Model, EventEmitter);
|
||||||
|
|
||||||
Model.fromClient = function (attributes) {
|
Model.fromClient = function (attributes) {
|
||||||
'use strict';
|
'use strict';
|
||||||
return new this(excludeExtraAttributes(attributes, this));
|
return new this(excludeExtraAttributes(attributes, this));
|
||||||
|
|
|
@ -130,8 +130,12 @@ _.extend(Repository.prototype, {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
save: function (model) {
|
save: function (model) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
model.emit('beforeCreate');
|
||||||
|
model.emit('beforeSave');
|
||||||
var id_and_rev = this.collection.save(model.forDB());
|
var id_and_rev = this.collection.save(model.forDB());
|
||||||
model.set(id_and_rev);
|
model.set(id_and_rev);
|
||||||
|
model.emit('afterSave');
|
||||||
|
model.emit('afterCreate');
|
||||||
return model;
|
return model;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -262,8 +266,11 @@ _.extend(Repository.prototype, {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
remove: function (model) {
|
remove: function (model) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var id = model.get('_id');
|
model.emit('beforeRemove');
|
||||||
return this.collection.remove(id);
|
var id = model.get('_id'),
|
||||||
|
result = this.collection.remove(id);
|
||||||
|
model.emit('afterRemove');
|
||||||
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -398,10 +405,14 @@ _.extend(Repository.prototype, {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
update: function (model, data) {
|
update: function (model, data) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
model.emit('beforeUpdate', data);
|
||||||
|
model.emit('beforeSave', data);
|
||||||
var id = model.get("_id") || model.get("_key"),
|
var id = model.get("_id") || model.get("_key"),
|
||||||
id_and_rev = this.collection.update(id, data);
|
id_and_rev = this.collection.update(id, data);
|
||||||
model.set(data);
|
model.set(data);
|
||||||
model.set(id_and_rev);
|
model.set(id_and_rev);
|
||||||
|
model.emit('afterSave', data);
|
||||||
|
model.emit('afterUpdate', data);
|
||||||
return model;
|
return model;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*global require, describe, expect, it, beforeEach, createSpyObj */
|
||||||
|
|
||||||
|
var FoxxRepository = require("org/arangodb/foxx/repository").Repository,
|
||||||
|
Model = require("org/arangodb/foxx/model").Model;
|
||||||
|
|
||||||
|
describe('Model Events', function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var collection, instance, repository;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
collection = createSpyObj('collection', [
|
||||||
|
'update',
|
||||||
|
'save',
|
||||||
|
'remove'
|
||||||
|
]);
|
||||||
|
instance = new Model({ random: '', beforeCalled: false, afterCalled: false });
|
||||||
|
repository = new FoxxRepository(collection, {model: Model});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be possible to subscribe and emit events', function () {
|
||||||
|
expect(instance.on).toBeDefined();
|
||||||
|
expect(instance.emit).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit beforeCreate and afterCreate events when creating the model', function () {
|
||||||
|
addHooks(instance, 'Create');
|
||||||
|
expect(repository.save(instance)).toEqual(instance);
|
||||||
|
expect(instance.get('beforeCalled')).toBe(true);
|
||||||
|
expect(instance.get('afterCalled')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit beforeSave and afterSave events when creating the model', function () {
|
||||||
|
addHooks(instance, 'Save');
|
||||||
|
expect(repository.save(instance)).toEqual(instance);
|
||||||
|
expect(instance.get('beforeCalled')).toBe(true);
|
||||||
|
expect(instance.get('afterCalled')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit beforeUpdate and afterUpdate events when updating the model', function () {
|
||||||
|
var newData = { newAttribute: 'test' };
|
||||||
|
addHooks(instance, 'Update', newData);
|
||||||
|
expect(repository.update(instance, newData)).toEqual(instance);
|
||||||
|
expect(instance.get('beforeCalled')).toBe(true);
|
||||||
|
expect(instance.get('afterCalled')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit beforeSave and afterSave events when updating the model', function () {
|
||||||
|
var newData = { newAttribute: 'test' };
|
||||||
|
addHooks(instance, 'Save', newData);
|
||||||
|
expect(repository.update(instance, newData)).toEqual(instance);
|
||||||
|
expect(instance.get('beforeCalled')).toBe(true);
|
||||||
|
expect(instance.get('afterCalled')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit beforeRemove and afterRemove events when removing the model', function () {
|
||||||
|
addHooks(instance, 'Remove');
|
||||||
|
repository.remove(instance);
|
||||||
|
expect(instance.get('beforeCalled')).toBe(true);
|
||||||
|
expect(instance.get('afterCalled')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function addHooks(model, ev, dataToReceive) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var random = String(Math.floor(Math.random() * 1000));
|
||||||
|
|
||||||
|
model.on('before' + ev, function (data) {
|
||||||
|
expect(this).toEqual(model);
|
||||||
|
expect(data).toEqual(dataToReceive);
|
||||||
|
this.set('random', random);
|
||||||
|
this.set('beforeCalled', true);
|
||||||
|
});
|
||||||
|
model.on('after' + ev, function (data) {
|
||||||
|
expect(this).toEqual(model);
|
||||||
|
expect(data).toEqual(dataToReceive);
|
||||||
|
this.set('afterCalled', true);
|
||||||
|
expect(this.get('beforeCalled')).toBe(true);
|
||||||
|
expect(this.get('random')).toEqual(random);
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue