如何在mongoose中自动创建必填字段

时间:2014-06-08 23:00:05

标签: node.js mongodb mongoose

我有一个mongoose架构,如下所示:

var userSchema = new Schema({
    username: {type: String, required: true, index: {unique: true}},
    usernameCanonical: {type: String, required: true, index: {unique: true}}
});


userSchema.pre("save", function () {
    this.usernameCanonical = this.username.toLowerCase();
    return next();  
});

我希望能够通过输入用户名来创建新用户,并让usernameCanonical自动生成模型。

var user = new User({ 
    username: "EXAMPLE_USERNAME"
});
user.save()

当我尝试这样做时,我从mongoose那里得到验证错误,说需要usernameCanonical。

Path `usernameCanonical` is required.

问题似乎是在验证后调用预保存挂钩。我不想每次保存新用户时都手动添加规范用户名。我也不想从架构中删除required选项。

有没有办法让mongoose模型自动生成必填字段?向模式中的usernameCanonical字段添加默认值似乎可以防止验证错误,但感觉就像是黑客。

1 个答案:

答案 0 :(得分:1)

正如levi所提到的,你应该使用 validate() hook:

Save/Validate Hooks

根据您的代码检查此工作示例:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const userSchema = new Schema({
  username: {type: String, required: true, index: {unique: true}},
  usernameCanonical: {type: String, required: true, index: {unique: true}}
});

userSchema.pre('validate', function () {
  if ((this.isNew || this.isModified) && this.username) {
    this.usernameCanonical = this.username.toLowerCase();
  }
});

const User = mongoose.model('user', userSchema);

mongoose.connect('mongodb://localhost:27017/uniqueTest')
  .then(() => {
    // create two users
    const user1 = new User({ 
      username: 'EXAMPLE_USERNAME-1'
    });
    const user2 = new User({ 
      username: 'EXAMPLE_USERNAME-2'
    });

    return Promise.all([
      user1.save(),
      user2.save()
    ]);
  })
  .then(() => {
    // update username
    return User.findOne({ username: 'EXAMPLE_USERNAME-1' })
      .then((user) => {
        user.username = 'EXAMPLE_USERNAME_UPDATED-1';
        return user.save();
      });
  })
  .then(() => mongoose.connection.close())
  .then(() => console.log('script finished successfully'))
  .catch((err) => {
    console.error(err);
    mongoose.connection.close()
      .then(() => process.exit(1));
  });

我希望这会有所帮助。