Ответ 1
требуемые валидаторы только терпят неудачу, когда вы пытаетесь явно отключить ключ.
Это не имеет никакого смысла для меня, но это то, что говорят документы.
У меня возникают проблемы с попыткой работать с параметром "runValidators". Моя пользовательская схема имеет поле электронной почты, для которого требуется значение true, но каждый раз, когда новый пользователь добавляется в базу данных (с использованием опции "upsert" ), а поле электронной почты пуст, оно не жалуется:
var userSchema = new mongoose.Schema({
facebookId: {type: Number, required: true},
activated: {type: Boolean, required: true, default: false},
email: {type: String, required: true}
});
findOneAndUpdate
код:
model.user.user.findOneAndUpdate(
{facebookId: request.params.facebookId},
{
$setOnInsert: {
facebookId: request.params.facebookId,
email: request.payload.email,
}
},
{upsert: true,
new: true,
runValidators: true,
setDefaultsOnInsert: true
}, function (err, user) {
if (err) {
console.log(err);
return reply(boom.badRequest(authError));
}
return reply(user);
});
Я понятия не имею, что я делаю неправильно, я просто следовал за документами: http://mongoosejs.com/docs/validation.html
В документах говорится следующее:
Обратите внимание, что в mongoose 4.x обновления проверяют только на операции $set и $unset. Например, нижеприведенное обновление будет выполнено, независимо от значения числа.
Я заменил $setOnInsert на $set, но имел тот же результат.
требуемые валидаторы только терпят неудачу, когда вы пытаетесь явно отключить ключ.
Это не имеет никакого смысла для меня, но это то, что говорят документы.
В мангусте делать то же самое в два этапа.
findOne()
.Model.save()
.Это обновит ваш документ.
Я создал плагин для проверки необходимых свойств модели перед выполнением операций обновления в мангусте.
Код плагина здесь
var mongoose = require('mongoose');
var _ = require('lodash');
var s = require('underscore.string');
function validateExtra(schema, options){
schema.methods.validateRequired = function(){
var deferred = Promise.defer();
var self = this;
try {
_.forEach(this.schema.paths, function (val, key) {
if (val.isRequired && _.isUndefined(self[key])) {
throw new Error(s.humanize(key) + ' is not set and is required');
}
});
deferred.resolve();
} catch (err){
deferred.reject(err);
}
return deferred.promise;
}
}
module.exports = validateExtra;
Должен быть вызван явно как метод из модели, поэтому я рекомендую привязать цепочку .then
до вызова обновления.
Плагин, используемый здесь
fuelOrderModel(postVars.fuelOrder).validateRequired()
.then(function(){
return fuelOrderModel.findOneAndUpdate({_id: postVars.fuelOrder.fuelOrderId},
postVars.fuelOrder, {runValidators: true, upsert: true,
setDefaultsOnInsert: true, new: true})
.then(function(doc) {
res.json({fuelOrderId: postVars.fuelOrder.fuelOrderId});
});
}, function(err){
global.saveError(err, 'server', req.user);
res.status(500).json(err);
});
используйте этот плагин: mongoose-unique-validator
При использовании таких методов, как findOneAndUpdate
, вам необходимо передать этот объект конфигурации:
{runValidators: true, context: 'query'}
т.
User.findOneAndUpdate(
{ email: '[email protected]' },
{ email: '[email protected]' },
{ runValidators: true, context: 'query' },
function(err) {
// ...
}