Skip to content

Commit 6085fac

Browse files
committed
Adds initial code to support passing associations when creating new instances (#162)
There are more stuff to do but at least creating new instances should be more easy for users.
1 parent 145719f commit 6085fac

File tree

2 files changed

+127
-43
lines changed

2 files changed

+127
-43
lines changed

lib/Instance.js

Lines changed: 104 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -65,22 +65,21 @@ function Instance(opts) {
6565
};
6666
return checkNextValidation();
6767
};
68+
var saveError = function (cb, err) {
69+
emitEvent("save", err, instance);
70+
Hook.trigger(instance, opts.hooks.afterSave, false);
71+
if (typeof cb == "function") {
72+
cb(err, instance);
73+
}
74+
};
6875
var saveInstance = function (cb) {
6976
if (!opts.is_new && opts.changes.length === 0) {
7077
return saveInstanceExtra(cb);
7178
}
7279

73-
var saveError = function (err) {
74-
emitEvent("save", err, instance);
75-
Hook.trigger(instance, opts.hooks.afterSave, false);
76-
if (typeof cb == "function") {
77-
cb(err, instance);
78-
}
79-
};
80-
8180
Hook.wait(instance, opts.hooks.beforeValidation, function (err) {
8281
if (err) {
83-
return saveError(err);
82+
return saveError(cb, err);
8483
}
8584

8685
for (var k in opts.properties) {
@@ -103,19 +102,19 @@ function Instance(opts) {
103102
if (opts.is_new) {
104103
return Hook.wait(instance, opts.hooks.beforeCreate, function (err) {
105104
if (err) {
106-
return saveError(err);
105+
return saveError(cb, err);
107106
}
108107
Hook.wait(instance, opts.hooks.beforeSave, function (err) {
109108
if (err) {
110-
return saveError(err);
109+
return saveError(cb, err);
111110
}
112111
return saveInstanceNext(cb);
113112
});
114113
});
115114
}
116115
Hook.wait(instance, opts.hooks.beforeSave, function (err) {
117116
if (err) {
118-
return saveError(err);
117+
return saveError(cb, err);
119118
}
120119
return saveInstanceNext(cb);
121120
});
@@ -124,12 +123,7 @@ function Instance(opts) {
124123
var saveInstanceNext = function (cb) {
125124
handleValidations(function (err) {
126125
if (err) {
127-
emitEvent("save", err, instance);
128-
Hook.trigger(instance, opts.hooks.afterSave, err === null);
129-
if (typeof cb == "function") {
130-
cb(err, instance);
131-
}
132-
return;
126+
return saveError(cb, err);
133127
}
134128

135129
var data = {};
@@ -148,22 +142,27 @@ function Instance(opts) {
148142

149143
if (opts.is_new) {
150144
opts.driver.insert(opts.table, data, opts.keys, function (save_err, info) {
151-
if (!save_err) {
152-
opts.changes.length = 0;
153-
for (var i = 0; i < opts.keys.length; i++) {
154-
opts.data[opts.keys[i]] = info[opts.keys[i]];
155-
}
156-
opts.is_new = false;
145+
if (save_err) {
146+
return saveError(cb, save_err);
157147
}
158-
emitEvent("save", save_err, instance);
159-
Hook.trigger(instance, opts.hooks.afterCreate, !save_err);
160-
Hook.trigger(instance, opts.hooks.afterSave, !save_err);
161-
if (typeof cb == "function") {
162-
if (save_err) {
163-
return cb(save_err, instance);
164-
}
165-
return saveInstanceExtra(cb);
148+
149+
opts.changes.length = 0;
150+
for (var i = 0; i < opts.keys.length; i++) {
151+
opts.data[opts.keys[i]] = info[opts.keys[i]];
166152
}
153+
opts.is_new = false;
154+
155+
saveAssociations(function (err) {
156+
emitEvent("save", err, instance);
157+
Hook.trigger(instance, opts.hooks.afterCreate, !err);
158+
Hook.trigger(instance, opts.hooks.afterSave, !err);
159+
if (typeof cb == "function") {
160+
if (err) {
161+
return cb(err, instance);
162+
}
163+
return saveInstanceExtra(cb);
164+
}
165+
});
167166
});
168167
} else {
169168
var changes = {}, conditions = {};
@@ -174,21 +173,73 @@ function Instance(opts) {
174173
conditions[opts.keys[i]] = data[opts.keys[i]];
175174
}
176175
opts.driver.update(opts.table, changes, conditions, function (save_err) {
177-
if (!save_err) {
178-
opts.changes.length = 0;
176+
if (save_err) {
177+
return saveError(cb, save_err);
179178
}
180-
emitEvent("save", save_err, instance);
181-
Hook.trigger(instance, opts.hooks.afterSave, !save_err);
182-
if (typeof cb == "function") {
183-
if (save_err) {
184-
return cb(save_err, instance);
179+
180+
opts.changes.length = 0;
181+
182+
saveAssociations(function (err) {
183+
emitEvent("save", err, instance);
184+
Hook.trigger(instance, opts.hooks.afterSave, !err);
185+
if (typeof cb == "function") {
186+
if (err) {
187+
return cb(err, instance);
188+
}
189+
return saveInstanceExtra(cb);
185190
}
186-
return saveInstanceExtra(cb);
187-
}
191+
});
188192
});
189193
}
190194
});
191195
};
196+
var saveAssociations = function (cb) {
197+
var pending = 0, errored = false, i, j;
198+
199+
for (i = 0; i < opts.one_associations.length; i++) {
200+
if (!instance.hasOwnProperty(opts.one_associations[i].name)) continue;
201+
202+
if (instance[opts.one_associations[i].name].isInstance) {
203+
pending += 1;
204+
205+
instance[opts.one_associations[i].setAccessor](instance[opts.one_associations[i].name], function (err) {
206+
if (err) {
207+
if (errored) return;
208+
209+
errored = true;
210+
return cb(err);
211+
}
212+
213+
if (--pending === 0) {
214+
return cb();
215+
}
216+
});
217+
}
218+
}
219+
220+
for (i = 0; i < opts.many_associations.length; i++) {
221+
if (!instance.hasOwnProperty(opts.many_associations[i].name)) continue;
222+
223+
pending += 1;
224+
225+
instance[opts.many_associations[i].setAccessor](instance[opts.many_associations[i].name], function (err) {
226+
if (err) {
227+
if (errored) return;
228+
229+
errored = true;
230+
return cb(err);
231+
}
232+
233+
if (--pending === 0) {
234+
return cb();
235+
}
236+
});
237+
}
238+
239+
if (pending === 0) {
240+
return cb();
241+
}
242+
};
192243
var saveInstanceExtra = function (cb) {
193244
if (opts.extrachanges.length === 0) {
194245
if (cb) return cb(null, instance);
@@ -422,6 +473,18 @@ function Instance(opts) {
422473
break;
423474
}
424475
}
476+
for (i = 0; i < opts.one_associations.length; i++) {
477+
if (opts.data.hasOwnProperty(opts.one_associations[i].name)) {
478+
instance[opts.one_associations[i].name] = opts.data[opts.one_associations[i].name];
479+
delete opts.data[opts.one_associations[i].name];
480+
}
481+
}
482+
for (i = 0; i < opts.many_associations.length; i++) {
483+
if (opts.data.hasOwnProperty(opts.many_associations[i].name)) {
484+
instance[opts.many_associations[i].name] = opts.data[opts.many_associations[i].name];
485+
delete opts.data[opts.many_associations[i].name];
486+
}
487+
}
425488

426489
Hook.trigger(instance, opts.hooks.afterLoad);
427490

lib/Model.js

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,29 @@ function Model(opts) {
3131
inst_opts = {};
3232
}
3333

34-
for (var k in data) {
34+
var found_assoc = false, i, k;
35+
36+
for (k in data) {
3537
if (k != "extra_field" && !opts.properties.hasOwnProperty(k) && opts.keys.indexOf(k) == -1
3638
&& association_properties.indexOf(k) == -1) {
37-
delete data[k];
39+
found_assoc = false;
40+
for (i = 0; i < one_associations.length; i++) {
41+
if (one_associations[i].name == k) {
42+
found_assoc = true;
43+
break;
44+
}
45+
}
46+
if (!found_assoc) {
47+
for (i = 0; i < many_associations.length; i++) {
48+
if (many_associations[i].name == k) {
49+
found_assoc = true;
50+
break;
51+
}
52+
}
53+
}
54+
if (!found_assoc) {
55+
delete data[k];
56+
}
3857
}
3958
}
4059

@@ -53,6 +72,8 @@ function Model(opts) {
5372
hooks : opts.hooks,
5473
methods : opts.methods,
5574
validations : opts.validations,
75+
one_associations : one_associations,
76+
many_associations : many_associations,
5677
association_properties : association_properties
5778
});
5879
if (model_fields !== null) {

0 commit comments

Comments
 (0)