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

Posted

技术标签:

【中文标题】如何在猫鼬中自动创建必填字段【英文标题】:How to automatically create a required field in mongoose 【发布时间】:2014-07-29 11:46:24 【问题描述】:

我有一个看起来像这样的猫鼬模式:

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 选项。

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

【问题讨论】:

我想你已经在这里发现了你自己的问题。当您从不打算提供值并且您总是要在预保存挂钩中计算它时,应该不需要将字段标记为“必需”,然后它就会否定逻辑。验证“必需”输入的含义正是它所说的。 试试schema.pre('validate', etc) 【参考方案1】:

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

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

我希望这会有所帮助。

【讨论】:

以上是关于如何在猫鼬中自动创建必填字段的主要内容,如果未能解决你的问题,请参考以下文章

在猫鼬中,如果我正在创建一个包含 4 个字段的模式。但我只保存两个字段的值。如何更新未给出的字段值?

如何在猫鼬中插入自动增量编号

在猫鼬中使用动态字段

在猫鼬中格式化日期

如何在猫鼬中为 geojson 数据创建模式?

如何通过填充字段在猫鼬中查找文档?