2

私はアプリケーションと呼ばれるモデルを持っています:

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の競合状態ですか?

4

1 に答える 1

0

バリデーターが非同期の場合 (ここにあるように)、検証が成功したかどうかに応じて、true または false で呼び出す必要があるコールバックである 2 番目のパラメーターを受け入れる必要があります。そう:

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すべてのドキュメントを取得して手動で検索する代わりに、フィルタを適用します。例えば

Application.find({name: name} ...

またはさらに良い:

一意のインデックスを作成し、namemongo に一意性を保証させます。例えば

var ApplicationSchema = new mongoose.Schema({
    name: {type: String, unique: true}, 
    ...
于 2012-06-06T00:04:51.873 に答える