Skip to content

Commit

Permalink
Adds hasMany hooks.beforeSave (#324)
Browse files Browse the repository at this point in the history
  • Loading branch information
dresende committed Sep 16, 2013
1 parent 7ceb120 commit 7425a5a
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 22 deletions.
58 changes: 36 additions & 22 deletions lib/Associations/Many.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var _ = require("lodash");
var InstanceConstructor = require("../Instance").Instance;
var Hook = require("../Hook");
var Settings = require("../Settings");
var Property = require("../Property");
var ErrorCodes = require("../ErrorCodes");
Expand Down Expand Up @@ -29,6 +30,7 @@ exports.prepare = function (Model, associations) {
break;
}
}

if (props === null) {
props = {};
} else {
Expand All @@ -43,6 +45,7 @@ exports.prepare = function (Model, associations) {
name : name,
model : OtherModel || Model,
props : props,
hooks : opts.hooks || {},
autoFetch : opts.autoFetch || false,
autoFetchLimit : opts.autoFetchLimit || 2,
// I'm not sure the next key is used..
Expand Down Expand Up @@ -321,20 +324,38 @@ function extendInstance(Model, Instance, Driver, association, opts, createInstan
}

var Association = Associations.pop();

Association.save(function (err) {
var saveAssociation = function (err) {
if (err) {
return cb(err);
}

var data = {};
Association.save(function (err) {
if (err) {
return cb(err);
}

for (var k in opts) {
data[k] = opts[k];
}
var data = {};

for (var k in opts) {
data[k] = opts[k];
}

if (Driver.hasMany) {
return Driver.hasMany(Model, association).add(Instance, Association, data, function (err) {
if (err) {
return cb(err);
}

savedAssociations.push(Association);

return saveNextAssociation();
});
}

if (Driver.hasMany) {
return Driver.hasMany(Model, association).add(Instance, Association, data, function (err) {
util.populateConditions(Model, Object.keys(association.mergeId), Instance, data);
util.populateConditions(association.model, Object.keys(association.mergeAssocId), Association, data);

Driver.insert(association.mergeTable, data, null, function (err) {
if (err) {
return cb(err);
}
Expand All @@ -343,21 +364,14 @@ function extendInstance(Model, Instance, Driver, association, opts, createInstan

return saveNextAssociation();
});
}

util.populateConditions(Model, Object.keys(association.mergeId), Instance, data);
util.populateConditions(association.model, Object.keys(association.mergeAssocId), Association, data);

Driver.insert(association.mergeTable, data, null, function (err) {
if (err) {
return cb(err);
}

savedAssociations.push(Association);

return saveNextAssociation();
});
});
};

if (Object.keys(association.props).length) {
Hook.wait(Association, association.hooks.beforeSave, saveAssociation, opts);
} else {
Hook.wait(Association, association.hooks.beforeSave, saveAssociation);
}
};

return saveNextAssociation();
Expand Down
125 changes: 125 additions & 0 deletions test/integration/association-hasmany-hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
var should = require('should');
var helper = require('../support/spec_helper');
var ORM = require('../../');

describe("hasMany hooks", function() {
var db = null;
var Person = null;
var Pet = null;

var setup = function (props, opts) {
return function (done) {
db.settings.set('instance.cache', false);

Person = db.define('person', {
name : String,
});
Pet = db.define('pet', {
name : String
});
Person.hasMany('pets', Pet, props || {}, opts || {});

return helper.dropSync([ Person, Pet ], done);
};
};

before(function(done) {
helper.connect(function (connection) {
db = connection;
done();
});
});

describe("beforeSave", function () {
var had_extra = false;

before(setup({
born : Date
}, {
hooks : {
beforeSave: function (extra, next) {
had_extra = (typeof extra == "object");
return next();
}
}
}));

it("should pass extra data to hook if extra defined", function (done) {
Person.create({
name : "John"
}, function (err, John) {
Pet.create({
name : "Deco"
}, function (err, Deco) {
John.addPets(Deco, function (err) {
should.not.exist(err);

had_extra.should.be.true;

return done();
});
});
});
});
});

describe("beforeSave", function () {
var had_extra = false;

before(setup({}, {
hooks : {
beforeSave: function (next) {
next.should.be.a("function");
return next();
}
}
}));

it("should not pass extra data to hook if extra defined", function (done) {
Person.create({
name : "John"
}, function (err, John) {
Pet.create({
name : "Deco"
}, function (err, Deco) {
John.addPets(Deco, function (err) {
should.not.exist(err);

return done();
});
});
});
});
});

describe("beforeSave", function () {
var had_extra = false;

before(setup({}, {
hooks : {
beforeSave: function (next) {
setTimeout(function () {
return next(new Error('blocked'));
}, 100);
}
}
}));

it("should block if error returned", function (done) {
Person.create({
name : "John"
}, function (err, John) {
Pet.create({
name : "Deco"
}, function (err, Deco) {
John.addPets(Deco, function (err) {
should.exist(err);
err.message.should.equal('blocked');

return done();
});
});
});
});
});
});

0 comments on commit 7425a5a

Please sign in to comment.