Skip to content

Commit

Permalink
Adds initial code to support passing associations when creating new i…
Browse files Browse the repository at this point in the history
…nstances (#162)

There are more stuff to do but at least creating new instances should
be more easy for users.
  • Loading branch information
dresende committed May 31, 2013
1 parent 145719f commit 6085fac
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 43 deletions.
145 changes: 104 additions & 41 deletions lib/Instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,21 @@ function Instance(opts) {
};
return checkNextValidation();
};
var saveError = function (cb, err) {
emitEvent("save", err, instance);
Hook.trigger(instance, opts.hooks.afterSave, false);
if (typeof cb == "function") {
cb(err, instance);
}
};
var saveInstance = function (cb) {
if (!opts.is_new && opts.changes.length === 0) {
return saveInstanceExtra(cb);
}

var saveError = function (err) {
emitEvent("save", err, instance);
Hook.trigger(instance, opts.hooks.afterSave, false);
if (typeof cb == "function") {
cb(err, instance);
}
};

Hook.wait(instance, opts.hooks.beforeValidation, function (err) {
if (err) {
return saveError(err);
return saveError(cb, err);
}

for (var k in opts.properties) {
Expand All @@ -103,19 +102,19 @@ function Instance(opts) {
if (opts.is_new) {
return Hook.wait(instance, opts.hooks.beforeCreate, function (err) {
if (err) {
return saveError(err);
return saveError(cb, err);
}
Hook.wait(instance, opts.hooks.beforeSave, function (err) {
if (err) {
return saveError(err);
return saveError(cb, err);
}
return saveInstanceNext(cb);
});
});
}
Hook.wait(instance, opts.hooks.beforeSave, function (err) {
if (err) {
return saveError(err);
return saveError(cb, err);
}
return saveInstanceNext(cb);
});
Expand All @@ -124,12 +123,7 @@ function Instance(opts) {
var saveInstanceNext = function (cb) {
handleValidations(function (err) {
if (err) {
emitEvent("save", err, instance);
Hook.trigger(instance, opts.hooks.afterSave, err === null);
if (typeof cb == "function") {
cb(err, instance);
}
return;
return saveError(cb, err);
}

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

if (opts.is_new) {
opts.driver.insert(opts.table, data, opts.keys, function (save_err, info) {
if (!save_err) {
opts.changes.length = 0;
for (var i = 0; i < opts.keys.length; i++) {
opts.data[opts.keys[i]] = info[opts.keys[i]];
}
opts.is_new = false;
if (save_err) {
return saveError(cb, save_err);
}
emitEvent("save", save_err, instance);
Hook.trigger(instance, opts.hooks.afterCreate, !save_err);
Hook.trigger(instance, opts.hooks.afterSave, !save_err);
if (typeof cb == "function") {
if (save_err) {
return cb(save_err, instance);
}
return saveInstanceExtra(cb);

opts.changes.length = 0;
for (var i = 0; i < opts.keys.length; i++) {
opts.data[opts.keys[i]] = info[opts.keys[i]];
}
opts.is_new = false;

saveAssociations(function (err) {
emitEvent("save", err, instance);
Hook.trigger(instance, opts.hooks.afterCreate, !err);
Hook.trigger(instance, opts.hooks.afterSave, !err);
if (typeof cb == "function") {
if (err) {
return cb(err, instance);
}
return saveInstanceExtra(cb);
}
});
});
} else {
var changes = {}, conditions = {};
Expand All @@ -174,21 +173,73 @@ function Instance(opts) {
conditions[opts.keys[i]] = data[opts.keys[i]];
}
opts.driver.update(opts.table, changes, conditions, function (save_err) {
if (!save_err) {
opts.changes.length = 0;
if (save_err) {
return saveError(cb, save_err);
}
emitEvent("save", save_err, instance);
Hook.trigger(instance, opts.hooks.afterSave, !save_err);
if (typeof cb == "function") {
if (save_err) {
return cb(save_err, instance);

opts.changes.length = 0;

saveAssociations(function (err) {
emitEvent("save", err, instance);
Hook.trigger(instance, opts.hooks.afterSave, !err);
if (typeof cb == "function") {
if (err) {
return cb(err, instance);
}
return saveInstanceExtra(cb);
}
return saveInstanceExtra(cb);
}
});
});
}
});
};
var saveAssociations = function (cb) {
var pending = 0, errored = false, i, j;

for (i = 0; i < opts.one_associations.length; i++) {
if (!instance.hasOwnProperty(opts.one_associations[i].name)) continue;

if (instance[opts.one_associations[i].name].isInstance) {
pending += 1;

instance[opts.one_associations[i].setAccessor](instance[opts.one_associations[i].name], function (err) {
if (err) {
if (errored) return;

errored = true;
return cb(err);
}

if (--pending === 0) {
return cb();
}
});
}
}

for (i = 0; i < opts.many_associations.length; i++) {
if (!instance.hasOwnProperty(opts.many_associations[i].name)) continue;

pending += 1;

instance[opts.many_associations[i].setAccessor](instance[opts.many_associations[i].name], function (err) {
if (err) {
if (errored) return;

errored = true;
return cb(err);
}

if (--pending === 0) {
return cb();
}
});
}

if (pending === 0) {
return cb();
}
};
var saveInstanceExtra = function (cb) {
if (opts.extrachanges.length === 0) {
if (cb) return cb(null, instance);
Expand Down Expand Up @@ -422,6 +473,18 @@ function Instance(opts) {
break;
}
}
for (i = 0; i < opts.one_associations.length; i++) {
if (opts.data.hasOwnProperty(opts.one_associations[i].name)) {
instance[opts.one_associations[i].name] = opts.data[opts.one_associations[i].name];
delete opts.data[opts.one_associations[i].name];
}
}
for (i = 0; i < opts.many_associations.length; i++) {
if (opts.data.hasOwnProperty(opts.many_associations[i].name)) {
instance[opts.many_associations[i].name] = opts.data[opts.many_associations[i].name];
delete opts.data[opts.many_associations[i].name];
}
}

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

Expand Down
25 changes: 23 additions & 2 deletions lib/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,29 @@ function Model(opts) {
inst_opts = {};
}

for (var k in data) {
var found_assoc = false, i, k;

for (k in data) {
if (k != "extra_field" && !opts.properties.hasOwnProperty(k) && opts.keys.indexOf(k) == -1
&& association_properties.indexOf(k) == -1) {
delete data[k];
found_assoc = false;
for (i = 0; i < one_associations.length; i++) {
if (one_associations[i].name == k) {
found_assoc = true;
break;
}
}
if (!found_assoc) {
for (i = 0; i < many_associations.length; i++) {
if (many_associations[i].name == k) {
found_assoc = true;
break;
}
}
}
if (!found_assoc) {
delete data[k];
}
}
}

Expand All @@ -53,6 +72,8 @@ function Model(opts) {
hooks : opts.hooks,
methods : opts.methods,
validations : opts.validations,
one_associations : one_associations,
many_associations : many_associations,
association_properties : association_properties
});
if (model_fields !== null) {
Expand Down

0 comments on commit 6085fac

Please sign in to comment.