2015-02-07 14 views
0

У меня есть сценарий в node/express/mongoose, где у меня есть пользователи, которые накапливают очки, и когда эта точка суммирует определенный порог, они «повышают уровень» (думают игры с точечными уровнями).Мангустационное обновление зависит от поля другого сеттера?

Я создал пользовательский сеттер в поле точек, который проверяет, изменилось ли значение и если оно пытается обновить поле уровня. Уровни определены в другой коллекции, но сохраняются как простые объекты 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; 
} 
+0

Вам не кажется, на самом деле 'сохранить()' ИНГ документ. – laggingreflex

+0

Я видел аналогичную проблему здесь http://thatextramile.be/blog/2011/08/using-mongooses-setters-to-get-calculated-properties/, где также нет явного сохранения(). Основываясь на этой статье, я предположил, что «это» сохраняется после возвращения функции - если это не так, то в этом моя проблема ... –

+0

Вы должны явно сохранить ее, чтобы сохранить изменения в базе данных. – laggingreflex

ответ

2

на основе @ laggingreflex свой комментарий, я попытался модифицировать this в рамках метода модели (т.е. не в Level.findOne() обратного вызова, а также изменений, которые путь были сохранялось без явного save() вызова.

Кроме того, у меня была довольно глупая ошибка, где я возвращался новое_значение из findOne` обратный вызов .. не уверен, что я думал, там ...

Короче, и это может быть очевидным для специалистов узел/экспресс/Mongoose, но вы можете изменить, кроме одного поля который вы сейчас используете, но в тот момент, когда вы оказываетесь в обратном вызове другого метода асинхронизации, вам нужно будет сделать явное 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;  
} 
Смежные вопросы