2015-06-26 5 views
1

Я пытаюсь определить, как выполнить асинхронную проверку для схемы Mongoose - в частности, это имя пользователя. TMK, чтобы убедиться, что имя пользователя уникально, мы должны вручную запросить базу данных, чтобы узнать, существует ли такое же имя пользователя. Это асинхронный запрос. Однако методология наличия свойства «validate:» для каждого элемента схемы, похоже, запрашивает синхронную функцию проверки. Другими словами, эта строка:Mongoose - асинхронная проверка объекта схемы

Validate: [validation.usernameValidator, «не является допустимым именем пользователя»]

, кажется, требует, чтобы usernameValidator быть синхронными, и проблема мне нужно, чтобы быть асинхронной, для причина выше.

Итак, у меня есть Mongoose схемы для пользователя, так как:

var validation = { 

     usernameValidator: function (candidate) { 
      return true; 
     }, 
     passwordValidator: function (candidate) { 
      return true; 
     } 
    }; 


    userSchema = mongoose.Schema({ 

     username: { 
      type: String, 
      isUnique: true, 
      required: true, 
      validate: [validation.usernameValidator, 'not a valid username'] 
     }, 
     passwordHash: { 
      type: String, 
      required: true, 
      validate: [validation.passwordValidator, 'not a valid password'] 
     }, 
     email: { 
      type: String, 
      isUnique: true, 
      required: true, 
      validate: [validation.emailValidator, 'not a valid email address'] 
     } 
    }); 

    userSchema.pre('save', function (next) { 

     var self = this; 
     if (!self.isModified('passwordHash')) { 
      return next(); 
     } 

     bcrypt.hash(self.passwordPreHash, SALT_WORK_FACTOR, function (err, hash) { 
      if (err) { 
       return next(err); 
      } 
      else if(hash == null){ 
       return next(new Error('null/undefined hash')); 
      } 
      else { 
       self.passwordHash = hash; 
       next(); 
      } 
     }); 
    }); 


//is the following function my best bet? 
     userSchema.path('username').validate(function (value, respond){                       
    this.findOne({ username: value }, function (err, user){                         
      if(user)                   respond(false);                               
     });                                     
}, 'This username has been already registered'); 

мой единственный вариант выйти из методологии validation.usernameValidator и проверки имени пользователя с userSchema.path («имя пользователя»). проверить ..?

ответ

2

Mongoose должен обрабатывать это при условии, что вы указываете unique: true на этом поле.

Например

userSchema = mongoose.Schema({ 

    username: { 
     type: String, 
     unique: true, 
     required: true 
    }, 
    passwordHash: { 
     type: String, 
     required: true 
    }, 
    email: { 
     type: String, 
     unique: true, 
     required: true 
    } 
}); 

Сложение:

Mongoose объявит уникальный индекс при условии, что вы задаете такие в вашей схеме (как это сделано в приведенном выше примере). Это предотвращает необходимость запроса в mongodb, чтобы увидеть, имеет ли другой документ поле того же значения. Вы можете прочитать об этом here.

Подробнее об уникальных указателях для mongodb here можно узнать больше, если вы хотите узнать больше об их поведении.

Примечание: Ошибка подтверждения не будет выбрана, если предоставлено не уникальное значение. Дополнительную информацию об этом см. В документах mongoose.

+0

Это уникальный или isUnique? –

+0

О, вот почему я использовал isUnique для этого, и это ничего не делало, спасибо. –

+1

Да, это было неправильно. Я не был уверен, что вы решили это по другой причине. См. Мои дополнения для получения дополнительной информации, которая может быть полезна при ее реализации. – tsturzl

Смежные вопросы