programing

Mongoose FindOneAndUpdate 및 실행 Validator가 작동하지 않습니다.

lastcode 2023. 7. 1. 08:45
반응형

Mongoose FindOneAndUpdate 및 실행 Validator가 작동하지 않습니다.

'검증인 실행' 옵션을 사용하는 데 문제가 있습니다.사용자 스키마에 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 작업에서만 실행됩니다.예를 들어, 아래 업데이트는 숫자 값에 관계없이 성공합니다.

$setOn을 교체했습니다.$set를 사용하여 삽입했지만 결과는 동일합니다.

키를 명시적으로 $unset하려고 할 때만 필수 검증자가 실패합니다.

이것은 저에게 말이 안 되지만 그것은 문서들이 말하는 것입니다.

다음 플러그인 사용: mongoose-computer-computer

다음과 같은 방법을 사용할 때findOneAndUpdate이 구성 개체를 전달해야 합니다.

runValidators: true, 컨텍스트: 'query' }

예를

User.findOneAndUpdate(
  { email: 'old-email@example.com' },
  { email: 'new-email@example.com' },
  { runValidators: true, context: 'query' },
  function(err) {
    // ...
}

몽구스는 두 단계로 같은 일을 합니다.

  1. 다음을 사용하여 결과 찾기findOne()방법.
  2. 필드 추가 및 문서 저장 방법Model.save().

문서가 업데이트됩니다.

findOneAndUpdate()에 대한 사전 후크를 추가하여 문제를 해결했습니다.

ExampleSchema.pre('findOneAndUpdate', function (next) {
    this.options.runValidators = true
    next()
})

그런 다음 findOneAndUpdate를 사용하면 유효성 검사가 작동합니다.

mongoose에서 업데이트 작업을 수행하기 전에 필요한 모델 속성을 확인하기 위해 플러그인을 만들었습니다.

플러그인 코드 여기

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);
    });

findOneAndUpdate로 유효성을 확인하려면 현재 문서를 가져올 수 없지만 이 키워드의 내용을 가져올 수 있으며 이 키워드의 내용에는 "op" 속성이 있으므로 솔루션은 다음과 같습니다.


참고: 컨텍스트 사용 여부는 중요하지 않습니다.또한 findOneAndUpdate 본문에 "price"와 "priceDiscount"가 모두 포함된 데이터를 보내는 것을 잊지 마십시오.

validate: {
        validator: function (value) {
          if (this.op === 'findOneAndUpdate') {
            console.log(this.getUpdate().$set.priceDiscount);
            console.log(this.getUpdate().$set.price);
            return (
              this.getUpdate().$set.priceDiscount < this.getUpdate().$set.price
            );
          }
          return value < this.price;
        },
        message: 'Discount price ({VALUE}) should be below regular price',
      }

mongoose가 문서를 삽입하는 것이 아니라 문서를 업데이트하는 것으로 가정하기 때문입니다.따라서 잘못된 모델에 업서트가 있을 수 있는 유일한 가능성은 다음을 수행하는 것입니다.$unset 다른말하면로,하면,findOneAndUpdate에 적합할 것입니다.PATCH종점의삽입에서 모델의 유효성을 검사하고 이 끝점에서도 업데이트를 수행할 수 있도록 하려면 다음과 같이 하십시오.PUT를 사용해야 .replaceOne

언급URL : https://stackoverflow.com/questions/31101984/mongoose-findoneandupdate-and-runvalidators-not-working

반응형