Подтвердить что ты не робот

Почему Mongoose не проверяет на обновление?

У меня есть этот код

var ClientSchema = new Schema({
  name: {type: String, required: true, trim: true}
});

var Client = mongoose.mode('Client', ClientSchema);

Используя express, я создаю новый клиент с этим кодом

var client = new Client(req.body);
client.save(function(err, data) {
  ....
});

Если я оставляю поле имени пустым в форме, mongoose не разрешает создавать клиент, потому что я устанавливаю его в соответствии с требованиями схемы. Кроме того, если я оставляю пробелы до и после имени, mongoose удаляет эти пробелы перед сохранением.

Теперь я пытаюсь обновить клиент с помощью этого кода

var id = req.params.id;
var client = req.body;
Client.update({_id: id}, client, function(err) {
  ....
});

Это позволило мне изменить имя, но если я оставлю его пустым в форме, mongoose не проверяет и не сохраняет пустое имя. Если я добавляю пустые пробелы до и после имени, он сохраняет имя с пробелами.

Почему mongoose проверяется при сохранении, но не при обновлении? Я делаю это не так?

mongodb: 2.4.0 мангуста: 3.6.0 экспресс: 3.1.0 node: 0.10.1

4b9b3361

Ответ 1

Вы не делаете ничего плохого, validation реализуется как внутреннее промежуточное ПО внутри Mongoose, а промежуточное программное обеспечение не выполняется во время update как это в основном переход к собственному драйверу.

Если вы хотите, чтобы ваше обновление клиента было проверено, вам нужно find обновить объект, применить к нему новые значения свойств (см. underscore extend), а затем наберите save на нем.

Обновление Mongoose 4.0

Как отмечено в комментариях и ответах victorkohl, Mongoose теперь поддерживает проверку полей операторов $set и $unset, когда вы включаете опцию runValidators: true в вызов update.

Ответ 2

Начиная с Mongoose 4.0 вы можете запускать валидаторы на update() и findOneAndUpdate() с помощью нового флага runValidators: true.

Mongoose 4.0 вводит опцию запуска валидаторов на update() и findOneAndUpdate(). При включении этой опции будут запущены валидаторы для всех полей, которые ваш вызов update() пытается выполнить $set или $unset.

Например, данная схема OP:

var ClientSchema = new Schema({
  name: {type: String, required: true, trim: true}
});

var Client = mongoose.model('Client', ClientSchema);

Передача флага при каждом обновлении

Вы можете использовать новый флаг следующим образом:

var id = req.params.id;
var client = req.body;
Client.update({_id: id}, client, { runValidators: true }, function(err) {
  ....
});

Использование флага на pre hook

Если вы не хотите устанавливать флаг каждый раз, когда вы что-то обновляете, вы можете установить крюк pre для findOneAndUpdate():

// Pre hook for `findOneAndUpdate`
ClientSchema.pre('findOneAndUpdate', function(next) {
  this.options.runValidators = true;
  next();
});

Затем вы можете update() использовать валидаторы без передачи флажка runValidators каждый раз.

Ответ 3

mongodb не запускает проверку при обновлении по умолчанию. чтобы проверка работала по умолчанию и при обновлении, перед подключением к mongodb вы можете установить только такие глобальные настройки:

mongoose.set('runValidators', true); // here is your global setting

mongoose.connect(config.database, { useNewUrlParser: true });
mongoose.connection.once('open', () => {
    console.log('Connection has been made, start making fireworks...');
}).on('error', function (error) {
    console.log('Connection error:', error);
});

и любая встроенная или пользовательская проверка будет выполняться при обновлении также

Ответ 4

В вашей модели, напр. Файл Category.js:

const CategorySchema = mongoose.Schema({
category_name : {
type : String,
required : [true, 'Category Name Is Required !'],
trim : true,
maxlength : [30, 'Category Name Is To Long !'],
unique : true,
});
const Category = module.exports = mongoose.model("Category",CategorySchema);

В вашем файле маршрута:

router.put("/",(req,res,next)=>{
  Category.findOneAndUpdate(
  {_id : req.body.categoryId},
  {$set : {category_name : req.body.category_name} },
  **{runValidators: true}**, function(err,result) {
    if(err){
      if(err.code === 11000){
       var duplicateValue = err.message.match(/".*"/);
       res.status(200).json({"defaultError":duplicateValue[0]+" Is Already Exsist !"});
       }else{
         res.status(200).json({"error":err.message} || {"defaultError":'Error But Not Understood !'});
       }
    }else{
     console.log("From category.js (Route File) = "+result);
     res.status(200).json({"success":"Category Updated Successfully!!"});
    }
});

Ответ 5

exports.updateGroup = (request, response, next) => {
    const requestObj = request.body;
    var conditions = {
        _id: request.body._id,
        communityId: request.body.communityId
    };
    var newValues = {
        $set: requestObj
    };
    Group.updateOne(conditions, newValues, { ***runValidators: true*** }, (err, group) => {
        if (err) return response.json({
            message: "Updation of group failed",
            error: err,
            status: 500
        });
        response.json(group);
    });
};

Вам нужно добавить {runValidators: true} в качестве третьего аргумента для валидации для работы при обновлении.