- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
据我了解, Mongoose 预保存 Hook 在将文档插入集合之前但在验证发生之后触发。因此,如果一次验证失败,则不会调用预保存 Hook 。
就我而言,无论如何都会调用它们:
下面的简单代码的作用是尝试创建一个模式,其中用户在注册时通过 _id 引用其他用户。添加了预保存 Hook ,可以自动将新用户的 ID 推送到其推荐列表中。
因此用户 a 在没有推荐的情况下注册 -> 确定
用户 b 作为推荐人向 a 注册 -> 确定
用户 b2 使用与 b 相同的电子邮件注册(不行,是唯一的)并引用 a -> 应该失败,并且不应将 b2 的 ID 推送到 a.references
架构:
var userSchema = new Schema({
email: {type:String, unique:true, required:true},
isVerified: {type:Boolean, default:false},
referredBy: {type:Schema.ObjectId, ref:'User'},
referred: [{type:Schema.ObjectId, ref:'User'}],
});
userSchema.pre('save', function (next) {
if (!this.isNew) return next();
if (!this.referredBy) return next();
User.findById(this.referredBy, function (err, doc) {
if (err) return next(err);
if (!doc) return next(new DbError(['referredBy not found: %s', this.referredBy]));
doc.referred.push(this._id);
doc.save(next);
}.bind(this));
});
userSchema.path('referredBy').validate(function (value, respond) {
User.findById(value, function (err, user) {
if (err) throw err;
if (!user) return respond(false);
respond(true);
});
}, 'doesntExit');
var User = mongoose.model('User', userSchema);
测试代码:
var a = new User();
a.email = 'a';
a.save(function () {
var b = new User();
b.email = 'b';
b.referredBy = a._id;
b.save(function () {
var b2 = new User();
b2.email = 'b';
b2.referredBy = a._id;
b2.save(function (err, doc) {
console.log('error:', err); // duplicate error is thrown, which is OK
console.log(!!doc); // this is false, which is OK
User.findById(a._id, function (err, result) {
console.log('# of referrals: ', result.referred.length); // 2, which is BAD
});
});
});
});
其他一切都检查完毕,抛出错误,发生失败,但无论如何都会保存所有预保存 Hook
知道如何解决这个问题或者验证 Hook 后是否有真正的预保存?
最佳答案
据我所知,如果您为referedBy路径提供异步验证函数,它将与预保存函数并行(有效)执行,而不是串行执行,这样会阻止预保存函数的执行。 -保存函数的执行。
您可以考虑将它们组合成一个函数,并且如果您想阻止更新referedBy对象的引用列表,直到之后,例如,电子邮件值的唯一约束已得到满足(这显然不会得到强制执行)直到实际的保存尝试),您可能希望将这部分逻辑保留在保存后 Hook 中。
干杯。
编辑
我已经通过多种方式研究过这个问题,现在一切似乎都相当清楚:
1) 自定义验证函数在预保存 Hook 之前执行,并且可以通过返回 false 来阻止预保存 Hook (当然还有保存本身)的执行。通过以下内容进行演示:
userSchema.pre('save', function (next) {
console.log('EXECUTING PRE-SAVE');
next();
});
userSchema.path('referredBy').validate(function (value, respond) {
console.log('EXECUTING referredBy VALIDATION')
respond(false);
}, 'doesntExit');
2) 不需要进行数据库查询来强制执行的内置验证器(例如“必需”约束)也会在预保存函数之前执行,并且可以阻止其执行。通过注释掉 b2 的电子邮件值分配而不是分配非唯一值来轻松演示:
var b2 = new User();
//b2.email = 'b';
b2.referredBy = a._id;
3) 需要进行数据库查询(例如强制唯一性)的内置验证器不会阻止预保存 Hook 执行。据推测,这是为了针对成功案例进行优化,否则必须涉及 1 个查询来检查唯一性,然后在通过唯一性验证后进行另一个查询以进行更新插入。
因此,验证(自定义或内置)确实在执行预保存 Hook 之前发生,除非内置验证需要执行数据库查询.
关于node.js - Mongoose 独特 :true pre-save hook calls hook before validation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21923043/
对于 Prometheus 指标集合,如标题,我真的找不到只能通过 type Summary 完成的用例。 ,似乎它们都可以通过 type Histogram 以某种方式完成还。 让我们以请求并发度量
这个问题在这里已经有了答案: Ignore case while using duplicated (1 个回答) 关闭 9 个月前。 使用不区分大小写的 unique(tolower(x)) 删除
应用程序监控服务的一个有用功能是每次发生新的、独特的错误/问题/异常时发送警报(例如电子邮件)(即不是每次发生)。要么只是第一次,要么最多每次 X 次(一天或一周等)。例如,这可以通过 Visual
应用程序监控服务的一个有用功能是每次发生新的、独特的错误/问题/异常时发送警报(例如电子邮件)(即不是每次发生)。要么只是第一次,要么最多每次 X 次(一天或一周等)。例如,这可以通过 Visual
我想要相当于 DB2 中 MySql 的 GROUP_CONCAT 功能。 我尝试过 DB2 的 XML Aggrigate 函数来合并 murows。 SELECT a.ID, sub
我正在运行 python 数据库迁移脚本 (Flask-Migrate) 并添加了 alembic.ddl.imp import DefaultImpl 来解决第一组错误,但现在我收到以下错误。我正在
我有一个逗号分隔的文件“myfile.csv”,其中第 5 列是日期/时间戳。 (mm/dd/yyyy hh:mm)。 我需要列出所有包含重复日期的行(有很多) 我正在通过 cygwin 为 WinX
我使用的是 MySQL 5.7。 我有一个表格如下: -------------------------------------------------- | id | currentcy_id |
所以我有一个像这样的 ng-repeat: Join Ride /md-switch> 但是,每个 md-switch 都有相同的模型,因此当我在 Control
据我了解, Mongoose 预保存 Hook 在将文档插入集合之前但在验证发生之后触发。因此,如果一次验证失败,则不会调用预保存 Hook 。 就我而言,无论如何都会调用它们: 下面的简单代码的作用
如果我对我的目标文件执行此 grep,我会得到例如 275 作为结果。 但是我想学习 awk,所以在 awk 中尝试了这个: awk 'BEGIN { count=0 } /my pattern/
我是一名优秀的程序员,十分优秀!