使用Mongoose Schema防止字段修改

时间:2018-05-26 15:16:04

标签: node.js mongoose

有没有办法用"不可修改的"设置字段?设置新的Mongoose Schema时设置(例如类型,必需等)?这意味着一旦创建了新文档,就无法更改此字段。

例如,像这样:

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

5 个答案:

答案 0 :(得分:1)

从Mongoose的5.6.0版本开始,我们可以在模式中使用render() { return ( {this.state.loading && !this.state.arrivedData3 && <p>Loading...</p>} {!this.state.loading && this.state.arrivedData3 && <p>Render data arrived 3...</p>} ) } (正好是immutable: true包中的上述答案)。典型的用例是用于时间戳记,但是在您的情况下,使用mongoose-immutable时,它像这样:

username

如果您尝试更新该字段,则猫鼬将忽略修改。

来源:What's New in Mongoose 5.6.0: Immutable Properties

答案 1 :(得分:0)

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

npm install mongoose-immutable --save

然后使用它:

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

答案 2 :(得分:0)

您只能使用Mongoose,在userSchema.pre中保存:

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

        return next();
    });

答案 3 :(得分:0)

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

  

尽管在使用update时将值强制转换为其适当的类型,但以下内容不适用:
  -默认值
  -二传手
  -验证器
  -中间件

     

如果需要这些功能,请使用首先检索文档的传统方法。

     

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 }形式的附加“选项”参数调用任何更新函数(例如,“ 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()或使用指定的验证选项参数更新函数时才这样做。

答案 4 :(得分:0)

我在修改字段时遇到了同样的问题。

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

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

  1. 更新
  2. UpdateOne
  3. FindOneAndUpdate
  4. UpdateMany
  5. 重新保存

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

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