猫鼬的.pre('init')何时确切被调用?

Del*_*_HF 2 mongoose node.js mongoose-schema

我想创建每个都有各自独特的访问“代码”的“游戏”。代码required在模式中,每次创建新游戏时,我都需要生成一个代码。

我认为schema.pre('init')这是生成此访问代码的好地方:

GameSchema.pre('init', function(next) {
    // Code generation logic happens here
    this.code = myNewlyGeneratedCode
    next()
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这返回一条错误消息: ValidationError: Game validation failed: code: Path 'code' is required.

为什么不起作用?我必须code在实例化新游戏之前创建一个吗?

lin*_*eus 5

如注释中所述,pre('save')是在将文档存储到数据库之前运行的中间件。pre('init')从mongodb查询返回的文档上会调用它们。

演示文档中间件顺序的最简单方法是一个简单的示例:

49768723.js

#!/usr/bin/env node
'use strict';

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
const Schema = mongoose.Schema;

var count = 0;

const schema = new Schema({
  name: String
});

function log(str) {
  console.log(`${++count}: ${str}`);
}

schema.pre('save', function () {
  log('pre-save');
});

schema.pre('init', function () {
  log('pre-init');
});

schema.post('save', function () {
  log('post-save');
});

schema.post('init', function () {
  log('post-init');
});

schema.pre('validate', function () {
  log('pre-validate');
});

schema.post('validate', function () {
  log('post-validate');
});

schema.pre('remove', function () {
  log('pre-remove');
});

schema.post('remove', function () {
  log('post-remove');
});


const Test = mongoose.model('test', schema);

const test = new Test({ name: 'Billy' });

async function main() {
  await test.save();
  log('saved');
  await Test.findOne({ _id: test.id });
  log('found');
  await test.remove();
  log('removed');
  return mongoose.connection.close();
}

main();
Run Code Online (Sandbox Code Playgroud)

输出

stack: ./49768723.js
1: pre-validate
2: post-validate
3: pre-save
4: post-save
5: saved
6: pre-init
7: post-init
8: found
9: pre-remove
10: post-remove
11: removed
stack:
Run Code Online (Sandbox Code Playgroud)

  • 您也可以在预保存挂钩中使用类似 ' if (this.isNew) { this.code = gencode() }' 的测试来生成代码。This.isNew 只会在第一次保存时为真(除非您稍后再次明确设置)。我认为这个策略稍微简洁一些,因为你的钩子的目的是“保存”一个特殊的属性而不是验证某些东西。 (2认同)