【问题标题】:Mongoose - passing parameters to pre save - does not work in update saveMongoose - 将参数传递给预保存 - 在更新保存中不起作用
【发布时间】:2013-12-29 19:47:57
【问题描述】:

我正在尝试传递一个参数以在 mongoose 模型上预先保存中间件,例如:

subject.save({ user: 'foo', correlationId: 'j3nd75hf...' }, function (err, subject, count) {
    ...
});

它被传递给两个预保存中间件

第一:

schema.pre('save', function (next) {
    // do stuff to model

    if (arguments.length > 1)
        next.apply(this, Array.prototype.slice.call(arguments, 1));
    else
        next();
});

然后:

schema.pre('save', function(next, metadata, callback) {
    // ...
    // create history doc with metadata
    // ...

    history.save(function(err, doc) {
        if(err) throw err;

        if (typeof metadata == 'object')
            next(callback);
        else
            next();
    });
});

它不适用于保存从数据库中获取的现有模型,但它适用于新创建的模型。

如果我删除参数它确实有效。

所以如果我打电话...

subject.save(function (err, subject, count) {
    ...
});

...它确实有效。

看起来回调从未真正回调过。所以也许它假设第一个参数是 save() 更新的回调。

对于创建,它确实可以传递参数

(new models.Subject(subjectInfo)).save({ user: user, correlation_id: correlationId }, function (err, subject, count) {
    if (err) throw err;

    ...
});

关于为什么它适用于创建时的 save() 而不是更新时的 save() 有什么想法吗?

谢谢!!

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    搜索再搜索,这是我推荐的。

    改为在虚拟领域中工作。

    schema.virtual('modifiedBy').set(function (userId) {
      if (this.isNew()) {
        this.createdAt = this.updatedAt = new Date;
        this.createdBy = this.updatedBy = userId;
      } else {
        this.updatedAt = new Date;
        this.updatedBy = userId;
      }
    });
    

    如果这对您没有帮助,您可能会发现这个其他答案很有帮助:https://stackoverflow.com/a/10485979/1483977

    或者这个 github 问题:

    https://github.com/Automattic/mongoose/issues/499

    this

    【讨论】:

    • 不知道为什么不赞成,似乎这个问题没有一个明确的解决方案,这是一个有用的答案。
    • @yellowmelon Haters 要讨厌 :-)
    【解决方案2】:

    model.save() 的元数为 1,该参数应该是回调函数。我仍然不完全确定您是如何设置所有内容的,因为您编写代码的风格有点陌生。模型的保存方法只能像这样接受回调:

    Subject.findOne({ id: id }, function (err, subject) {
      subject.set('someKey', 'someVal');
    
      // You can only pass one param to the model's save method
      subject.save(function (err, doc, numAffected) {
    
      });
    });
    

    对于猫鼬的更新,我们这样做:

    Subject.update({ id: id}, function (err, numAffected) {
      // There is no doc to save because update() bypasses Subject.schema
    });
    

    此链接显示了 Model.save() 的定义位置。你会注意到它只接受一个参数: https://github.com/LearnBoost/mongoose/blob/3.8.x/lib/model.js#L167

    【讨论】:

    • 这仅适用于 Model.update、findByIdAndUpdate、findOneAndUpdate、findOneAndRemove、findByIdAndRemove。我正在调用保存()。当传递的参数被删除时,它也可以调用所有中间件
    • 嗯...我明白你现在在问什么。你能分享你的代码的“创建”部分吗?忠告,用猫鼬的话来说,保存、创建和更新的想法都有非常不同的含义。当你说“更新”时,大多数人会想到 MongoDB 的原生更新命令。这就是我困惑的根源
    • 是的,我只是在精神上将其分解为 CRUD 操作之一。我假设当模型/文档不是新的(!isNew)时,它确实使用了 mongodb update() 调用,但使用 save() 使用了钩子。 save() 上的钩子是否可能以不同的方式连接创建与更新?
    • 除了参数之外,不是保存函数。这是钩子中间件。这就是您调用next(callback) 的原因,这就是将回调get 传递给实际保存函数的地方。显然,它确实允许至少在大多数时间传递一些参数
    • (new models.Subject(subjectInfo)).save({ user: user, correlation_id: correlationId }, function (err, subject, count) {}); 在这一行中,(new models.Subject(subjectInfo)) 是从哪里来的?如果它返回一个模型,那么你不能传递两个参数来保存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 2018-01-14
    • 2015-11-12
    • 1970-01-01
    • 2016-02-01
    • 2021-05-27
    相关资源
    最近更新 更多