Make sure batch create calls back with correct data

See https://github.com/strongloop/loopback/issues/1031
This commit is contained in:
Raymond Feng 2015-01-29 11:52:39 -08:00
parent ce39f8ab01
commit 7d42202d40
2 changed files with 53 additions and 31 deletions

View File

@ -160,39 +160,38 @@ DataAccessObject.create = function (data, callback) {
}
if (Array.isArray(data)) {
var instances = [];
var errors = Array(data.length);
var gotError = false;
var wait = data.length;
if (wait === 0) {
callback(null, []);
}
for (var i = 0; i < data.length; i += 1) {
(function (d, i) {
Model = self.lookupModel(d); // data-specific
instances.push(Model.create(d, function (err, inst) {
if (err) {
errors[i] = err;
gotError = true;
}
modelCreated();
}));
})(data[i], i);
}
return instances;
function modelCreated() {
if (--wait === 0) {
callback(gotError ? errors : null, instances);
if(!gotError) {
instances.forEach(function(inst) {
inst.constructor.emit('changed');
});
}
// Undefined item will be skipped by async.map() which internally uses
// Array.prototype.map(). The following loop makes sure all items are
// iterated
for (var i = 0, n = data.length; i < n; i++) {
if (data[i] === undefined) {
data[i] = {};
}
}
async.map(data, function(item, done) {
self.create(item, function(err, result) {
// Collect all errors and results
done(null, {err: err, result: result || item});
});
}, function(err, results) {
if (err) {
return callback && callback(err, results);
}
// Convert the results into two arrays
var errors = null;
var data = [];
for (var i = 0, n = results.length; i < n; i++) {
if (results[i].err) {
if (!errors) {
errors = [];
}
errors[i] = results[i].err;
}
data[i] = results[i].result;
}
callback && callback(errors, data);
});
return data;
}
var enforced = {};

View File

@ -153,6 +153,29 @@ describe('manipulation', function () {
}).should.be.instanceOf(Array);
}).should.have.lengthOf(3);
});
it('should create batch of objects with beforeCreate', function(done) {
Person.beforeCreate = function(next, data) {
if (data && data.name === 'A') {
return next(null, {id: 'a', name: 'A'});
} else {
return next();
}
};
var batch = [
{name: 'A'},
{name: 'B'},
undefined
];
Person.create(batch, function(e, ps) {
should.not.exist(e);
should.exist(ps);
ps.should.be.instanceOf(Array);
ps.should.have.lengthOf(batch.length);
ps[0].should.be.eql({id: 'a', name: 'A'});
done();
});
});
});
describe('save', function () {