来自另一个字段的setter的Mongoose更新依赖字段?

时间:2015-02-07 17:04:19

标签: node.js mongoose

我在node / express / mongoose中有一个场景,我有积累积分的用户,当积分超过某个阈值时,他们会升级" (想想基于点数的游戏)。

我在points字段上创建了一个自定义setter,用于检查值是否已更改,如果是,则尝试更新level字段。级别在另一个集合中定义,但在与用户文档关联时保存为简单的JSON对象(因此查询中的.lean())。为了提高效率,我这样做是为了虚拟场或人口。

问题:这实际上似乎并未更新用户级别'应该的时候。我究竟做错了什么?

// Define our user schema
var UserSchema = new mongoose.Schema({
    ...
    points:       {type: Number, default: 0, set: pointsChangeHandler},
    level:        {name: String, minPoints: Number, maxPoints: Number},
    ...
});

这个二传手看起来像这样:

function goodPointsChangeHandler(newValue) {
    var self = this;
    if (newValue != self.goodPoints) {
        console.log('Point change detected.');
        // Find level that corresponds with new point total
        Level.findOne({
            'minPoints': {$lte : self.goodPoints},
            'maxPoints': {$gt : self.goodPoints}}, '-_id').lean().exec(function(err, level) {
            if (self.goodLevel == undefined || self.goodLevel.rank != level.rank) {
                console.log('Level changed.');
                self.goodLevel = level;
            }
            return newValue;
        });
    }
    return newValue;
}

1 个答案:

答案 0 :(得分:3)

基于@laggingreflex的评论,我尝试在模型方法的范围内修改this(即不在Level.findOne()回调中,并且以 的方式进行的更改仍然存在没有明确的save()电话。

另外,我有一个非常愚蠢的错误,我从 findOne`回调中返回newValue ..不知道我在想那里......

长话短说,这对于节点/快递/猫鼬专家来说可能是显而易见的,但是你可以修改除了你当前的setter方法之外的字段in,但是当你发现自己处于另一个异步方法的回调时,你必须做一个明确的save(),否则你对this的修改将不会被保留。

所以:

function myFieldSetterMethod(newValue) {
    this.myField = "a";
    this.myOtherField = "b";
    return newValue;
    // no save() necessary, this will update both fields
}

function myFieldSetterMethod(newValue) {
    this.myField = "a";

    SomeModel.findOne(..., function(err, doc) {
        this.myOtherField = doc.somethingIWantFromThisDoc;
        // now you'll need an explicit save
        // this.save(...)
    });

    return newValue;      
}