Skip to content
This repository was archived by the owner on Feb 10, 2022. It is now read-only.

Commit f55f1d6

Browse files
author
vdemedes
committed
hooks
1 parent 618230a commit f55f1d6

File tree

4 files changed

+325
-12
lines changed

4 files changed

+325
-12
lines changed

Readme.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
ES6 generator-based MongoDB ODM for Node.js v0.11.x.
44

5+
## Features
6+
7+
- Based on ES6 generators, which means **no callbacks**
8+
- Common, established API you've already used to
9+
- Hooks (before:save, around:create, after:remove, etc)
10+
- Very simple and easy-to-understand implementation
11+
- Fully covered by tests
12+
513
## Installation
614

715
```
@@ -39,6 +47,8 @@ Mongorito.close(); // alias for disconnect
3947

4048
#### Define a model
4149

50+
That's right. No schema.
51+
4252
```javascript
4353
var Post = Model.extend({
4454
collection: 'posts'
@@ -112,6 +122,53 @@ Or you can remove multiple documents using:
112122
yield Post.remove({ title: 'Some title' }); // query
113123
```
114124

125+
### Hooks
126+
127+
Mongorito models support *before*, *create* and *around* (*before* + *create*) hooks for these events:
128+
129+
- save (executes on both create and update)
130+
- create
131+
- update
132+
- remove
133+
134+
To setup a hook for some event:
135+
136+
```javascript
137+
var Post = Model.extend({
138+
collection: 'posts',
139+
140+
customHandling: function *(next) {
141+
// processing, validating, etc
142+
143+
yield next; // MUST be present
144+
}.before('save')
145+
});
146+
```
147+
148+
Same goes for other hooks:
149+
150+
```javascript
151+
myAfterCreateHook: function *(next) {
152+
// executes after document was created
153+
154+
yield next;
155+
}.after('create'),
156+
157+
myAroundRemoveHook: function *(next) {
158+
// executes before and after document was removed
159+
160+
yield next;
161+
}.around('remove')
162+
```
163+
164+
If you want to break the chain and prevent executing of the next hooks, just throw an **Error**:
165+
166+
```javascript
167+
myHook: function *(next) {
168+
throw new Error('Next hooks will not be executed');
169+
}.before('update')
170+
```
171+
115172
## Tests
116173

117174
To execute tests run:

lib/mongorito.js

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var Class = require('backbone-class');
2+
var compose = require('koa-compose');
23
var monk = require('monk');
34
var wrap = require('co-monk');
45

@@ -31,12 +32,40 @@ var Mongorito = {
3132
* Model
3233
*/
3334

35+
Function.prototype.before = function (action) {
36+
this.hook = {
37+
when: 'before',
38+
action: action
39+
};
40+
41+
return this;
42+
};
43+
44+
Function.prototype.after = function (action) {
45+
this.hook = {
46+
when: 'after',
47+
action: action
48+
};
49+
50+
return this;
51+
};
52+
53+
Function.prototype.around = function (action) {
54+
this.hook = {
55+
when: 'around',
56+
action: action
57+
};
58+
59+
return this;
60+
};
61+
3462
var Model;
3563

3664
var InstanceMethods = {
3765
initialize: function (attrs) {
3866
this.attributes = attrs || {};
3967
this.collection = Mongorito.collection(this.collection);
68+
this.configure();
4069
},
4170

4271
get: function (key) {
@@ -61,40 +90,102 @@ var InstanceMethods = {
6190
return this.attributes[key] = value;
6291
},
6392

93+
configure: function () {
94+
this.hooks = {
95+
before: {
96+
create: [],
97+
update: [],
98+
remove: [],
99+
save: []
100+
},
101+
after: {
102+
create: [],
103+
update: [],
104+
remove: [],
105+
save: []
106+
}
107+
};
108+
109+
for (var name in this) {
110+
var fn = this[name];
111+
112+
if (fn.hook) {
113+
var action = fn.hook.action;
114+
var when = fn.hook.when;
115+
116+
delete fn.hook;
117+
118+
switch (when) {
119+
case 'before':
120+
case 'after':
121+
this.hooks[when][action].push(fn);
122+
break;
123+
124+
case 'around':
125+
this.hooks['before'][action].push(fn);
126+
this.hooks['after'][action].unshift(fn);
127+
break;
128+
}
129+
}
130+
}
131+
},
132+
133+
runHooks: function *(when, action) {
134+
yield compose(this.hooks[when][action]).call(this);
135+
},
136+
64137
save: function *() {
65138
var id = this.get('_id');
66139
var fn = id ? this.update : this.create;
67140

68-
return yield fn.call(this);
141+
yield this.runHooks('before', 'save');
142+
143+
var result = yield fn.call(this);
144+
145+
yield this.runHooks('after', 'save');
146+
147+
return result;
69148
},
70149

71150
create: function *() {
151+
yield this.runHooks('before', 'create');
152+
72153
var collection = this.collection;
73154
var attrs = this.attributes;
74155

75156
var doc = yield collection.insert(attrs);
76157

77158
this.set('_id', doc._id);
78159

160+
yield this.runHooks('after', 'create');
161+
79162
return this;
80163
},
81164

82165
update: function *() {
166+
yield this.runHooks('before', 'update');
167+
83168
var collection = this.collection;
84169
var attrs = this.attributes;
85170

86171
yield collection.updateById(attrs._id, attrs);
87172

173+
yield this.runHooks('after', 'update');
174+
88175
return this;
89176
},
90177

91178
remove: function *() {
179+
yield this.runHooks('before', 'remove');
180+
92181
var collection = this.collection;
93182

94183
yield collection.remove({
95184
_id: this.get('_id')
96185
});
97186

187+
yield this.runHooks('after', 'remove');
188+
98189
return this;
99190
}
100191
};

package.json

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
{
22
"name": "mongorito",
3-
"version": "0.4.0",
3+
"version": "0.4.1",
44
"description": "ES6 generator-based MongoDB ODM. It rocks.",
55
"author": "Vadim Demedes <vdemedes@gmail.com>",
66
"dependencies": {
77
"backbone-class": "0.0.1",
88
"co": "^3.1.0",
99
"co-monk": "^1.0.0",
10+
"koa-compose": "^2.3.0",
1011
"monk": "^0.9.0"
1112
},
1213
"devDependencies": {
@@ -16,23 +17,23 @@
1617
},
1718
"main": "./index.js",
1819
"scripts": {
19-
"test": "./node_modules/.bin/mocha --harmony"
20+
"test": "./node_modules/.bin/mocha --harmony"
2021
},
2122
"repository": {
22-
"type": "git",
23-
"url": "https://github.com/vdemedes/mongorito"
23+
"type": "git",
24+
"url": "https://github.com/vdemedes/mongorito"
2425
},
2526
"bugs": {
2627
"url": "https://github.com/vdemedes/mongorito/issues"
2728
},
2829
"keywords": [
29-
"mongo",
30-
"mongodb",
31-
"co-mongo",
32-
"co-mongodb",
33-
"orm",
34-
"odm",
35-
"es6"
30+
"mongo",
31+
"mongodb",
32+
"co-mongo",
33+
"co-mongodb",
34+
"orm",
35+
"odm",
36+
"es6"
3637
],
3738
"license": "MIT"
3839
}

0 commit comments

Comments
 (0)