我有一个名为Application的模型:
var ApplicationSchema = new mongoose.Schema({
name : {type: String, validate: [uniqueName, 'Unique Name']},
dateCreated: Date,
containers : [ContainerSchema]
});
mongoose.model('Application', ApplicationSchema);
var Application = database.model('Application');
在保存时调用名为uniqueName的验证函数:
function uniqueName(name)
{
console.log('In Unique Name function');
Application.find({}, function(error, documents) {
for(var i = 0; i < documents.length; i++) {
if(documents[i].name == name) {
console.log('About to return false');
return false;
}
}
});
return true;
}
稍后在代码中我将一些数据放入模型并保存:
newApplication.name = request.body.name;
newApplication.save(function(error) {
console.log('Callback for save');
if(error) {
console.log('error if statement');
response.statusCode = 409;
response.end();
}
console.log('Done with callback');
});
response.statusCode = 201;
response.end();
当我使用一个非唯一的名称测试时,我得到了201响应以及来自终端的以下输出:
In Unique Name function
Callback for save
Done with callback
About to return false
我做错了什么,或者这真的是Mongoose的竞争条件?
答案 0 :(得分:0)
当您的验证器是异步的(就像在这里一样)时,它需要接受第二个参数,该参数是必须使用true或false调用的回调,具体取决于验证是否通过。所以:
function uniqueName(name, callback)
{
Application.find({}, function(error, documents) {
for(var i = 0; i < documents.length; i++) {
if(documents[i].name == name) {
return callback(false);
}
}
return callback(true);
}
}
然而,这不是很有效;你应该:
过滤您的find
,而不是获取所有文档并手动搜索它们。 e.g。
Application.find({name: name} ...
或更好:
在name
上创建一个唯一索引,让mongo确保您的唯一性。 e.g。
var ApplicationSchema = new mongoose.Schema({
name: {type: String, unique: true},
...