I have a Sails.js model called "products" which is a MongoDB collection. In the model, I have a beforeCreate()
hook that generates a unique productId like '170921-00001' in the format 'YYMMDD-count` where count is the record number created for the day. This is what my model looks like:
module.exports = {
attributes: {
name: { type: 'string', required: true },
productId: { type: 'string', unique: true }
},
beforeCreate: function(values, next) {
var moment = require('moment');
// Generate the productId
Products.count({
createdAt: {
'>=': moment().format('YYYY-MM-DD'),
'<': moment(moment().format('YYYY-MM-DD')).add(1, 'days').format('YYYY-MM-DD')
}
}).exec(function(error, productCount) {
if (error) {
throw error;
}
var count = '',
totalPlaces = 5 - productCount.toString().length;
while (totalPlaces > 0) {
count = count + '0';
totalPlaces--;
}
values.productId = moment().format('YYMMDD') + '-' + (count + productCount);
next();
});
}
};
The issue is, this break when I am trying to insert multiple products into the collection in a single database call. I get the following error:
debug: Error (E_VALIDATION) :: 1 attribute is invalid
MongoError: E11000 duplicate key error index: my-app.products.$productId_1 dup key: { : "170921-00002" }
at Function.MongoError.create (/Users/Nag/Code/my-app/web-service/node_modules/sails-mongo/node_modules/mongodb-core/lib/error.js:31:11)
at toError (/Users/Nag/Code/my-app/web-service/node_modules/sails-mongo/node_modules/mongodb/lib/utils.js:114:22)
at /Users/Nag/Code/my-app/web-service/node_modules/sails-mongo/node_modules/mongodb/lib/collection.js:658:23
at handleCallback (/Users/Nag/Code/my-app/web-service/node_modules/sails-mongo/node_modules/mongodb/lib/utils.js:95:56)
at resultHandler (/Users/Nag/Code/my-app/web-service/node_modules/sails-mongo/node_modules/mongodb/lib/bulk/ordered.js:421:14)
at /Users/Nag/Code/my-app/web-service/node_modules/sails-mongo/node_modules/mongodb-core/lib/connection/pool.js:455:18
at /Users/Nag/Code/my-app/web-service/node_modules/async-listener/glue.js:188:31
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickDomainCallback (internal/process/next_tick.js:128:9)
at process.fallback (/Users/Nag/Code/my-app/web-service/node_modules/async-listener/index.js:529:15)
Invalid attributes sent to undefined:
• productId
• A record with that `productId` already exists (`170921-00002`).
When I insert a single record, it works fine but when I insert multiple records, the first record gets inserted but every subsequent record generates that error. Is it because the document is getting inserted before the hook computes the productId
before even it has completed inserting the previous record? How do I solve this?