首页 文章

使用Mongoose Schema防止字段修改

提问于
浏览
3

在定义新的Mongoose Schema时,有没有办法设置具有“不可修改”设置的字段(如类型,必需等)?这意味着一旦创建了新文档,就无法更改此字段 .

例如,像这样:

var userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
    unmodifiable: true
  }
})

4 回答

  • 0

    你可以使用Mongoose Immutable . 这是一个可以使用下面的命令安装的小包,它允许您使用"immutable"属性 .

    npm install mongoose-immutable --save
    

    然后使用它:

    var userSchema = new mongoose.Schema({
        username: {
            type: String,
            required: true,
            immutable: true
        }
    });
    userSchema.plugin(immutablePlugin);
    
  • 0

    您只能使用Mongoose,在userSchema.pre中执行以下操作:

    userSchema.pre('save', function (next) {
            if (this.isModified(unmodifiable)) {
                return next(new Error('Trying to modify restricted data')
            }
    
            return next();
        });
    
  • 0

    请注意,文档明确指出,在标识符/名称中使用带更新的函数时,不会触发“预先”中间件:

    虽然在使用更新时将值转换为适当的类型,但以下内容不适用: - defaults - setters - validators - middleware如果需要这些功能,请使用首先检索文档的传统方法 . Model.findOne({name:'borne'},function(err,doc){if(err).. doc.name ='jason bourne'; doc.save(callback);})

    因此,要么通过mongooseAPI采用上述方式,它可以触发中间件(如desoares回答中的'pre')或触发您自己的验证器,例如:

    const theOneAndOnlyName = 'Master Splinter';
    const UserSchema = new mongoose.Schema({
      username: {
        type: String,
        required: true,
        default: theOneAndOnlyName
        validate: {
          validator: value => {
            if(value != theOneAndOnlyName) {
              return Promise.reject('{{PATH}} do not specify this field, it will be set automatically');
              // message can be checked at error.errors['username'].reason
            }
            return true;
          },
          message: '{{PATH}} do not specify this field, it will be set automatically'
        }
      }
    });
    

    或者总是使用 { runValidators: true } 形式的附加'options'参数调用任何更新函数(例如'findByIdAndUpdate'和朋友),例如:

    const splinter = new User({ username: undefined });
    User.findByIdAndUpdate(splinter._id, { username: 'Shredder' }, { runValidators: true })
      .then(() => User.findById(splinter._id))
      .then(user => {
        assert(user.username === 'Shredder');
    
        done();
      })
      .catch(error => console.log(error.errors['username'].reason));
    

    您也可以以非标准方式使用验证器功能,即:

    ...
    validator: function(value) {
      if(value != theOneAndOnlyName) {
        this.username = theOneAndOnlyName;
      }
      return true;
    }
    ...
    

    这不会抛出'ValidationError'但会悄悄地覆盖指定的值 . 当使用 save() 或使用指定的验证选项参数更新函数时,它仍然只会这样做 .

  • 0

    我对字段修改有同样的问题 .

    试试https://www.npmjs.com/package/mongoose-immutable-plugin

    该插件将拒绝对某个字段的每次修改尝试,并且它适用于

    • 更新

    • UpdateOne

    • FindOneAndUpdate

    • UpdateMany

    • 重新保存

    它支持数组,嵌套对象等类型的字段和保护深度不变性 .

    插件还处理更新选项,如$ set,$ inc等 .

相关问题