从Mongoose中间件访问旧模型属性

时间:2013-01-30 22:34:48

标签: node.js mongoose

我有一个Category模型,它的唯一属性是name

还有一个SubCategory模型,其中包含namecategory字符串字段,其中包含Category模型的名称。

Category模型的name发生更改时,指向该类别的每个SubCategory都应更新其category字段以匹配新名称。

我目前正在路由处理程序上直接实现这一点,方法是将所有SubCategories指向某个类别,迭代它们并更新它的类别字段。

我想在模型中实现这个逻辑,它应该属于它。

我在Category模型上创建了一个预中间件,

CategorySchema.pre('save', function(next) {
  console.log('Saving ' + this.name);
  next();
});

负责PUT请求的路由处理程序使用更新的名称保存模型,如下所示:

...
parentCategory.name = requestedName;
parentCategory.validate(function(validationError) {          
  if (validationError) {
    return res.send(response.BAD_REQUEST); 
  }     
  parentCategory.save(function(saveError) {       
    if(saveError) {
      return res.send(response.SERVER_ERROR);        
    }
  });
});
...

但是我打印了 NEW 名称,因此我无法迭代它的子类别,因为我只能访问新名称。

我不确定我应该如何将旧名称和新名称都传递给中间件以执行其中的操作。

2 个答案:

答案 0 :(得分:2)

我可以通过查询类别模型来访问旧值:

CategorySchema.pre('save', function(next) {
    var that = this;
    var updateEachSubCategory = function(subcategory) {
    subcategory.category = that.name;
    subcategory.save(function(saveError) {
      if(saveError) {
        console.log(saveError);
        return 1;                    
      }
    });
  };
    var updateChildrenCategoryField = function(err, subCategoriesArray) {
        solange.asyncFor(subCategoriesArray, updateEachSubCategory);   
    };
    var findChildren = function(categorySearchError, categoryFound) {
        if(!categorySearchError) {
            mongoose.models["SubCategory"].find({ category: categoryFound.name }, updateChildrenCategoryField);
        }
    };
    mongoose.models["Category"].findOne({ _id: this._id }, findChildren);
    next();
});

由于这是一个保存中间件,新名称尚未保存,因此我们可以通过查询模型来访问它。

答案 1 :(得分:0)

我的解决方案是在post init中间件中备份属性值

schema.post('init', function(model) {
  model.oldValues = JSON.parse(JSON.stringify(model));
}

我们可以在任何其他中间件中访问这些属性,例如在修改属性之前this.someAttr === this.oldValues.someAttr

我写了gist to check it

以下是它的输出:

    ------------------
    Pre init attributes
    The doc is new, run app once again
    ------------------
    ------------------
    Post init attributes
    { _id: 55a37cc88ff0f55e6ee9be2d,
      name: 'Test 1 - 12:07:88',
      __v: 0,
      ready: true }
    Setting this.oldValues
    ------------------
    ------------------
    Pre save attributes
    { _id: 55a37cc88ff0f55e6ee9be2d,
      name: 'Test 1 - 12:07:16',
      __v: 0,
      ready: false }
    ------------------
    ------------------
    Post save attributes
    { _id: 55a37cc88ff0f55e6ee9be2d,
      name: 'Test 1 - 12:07:16',
      __v: 0,
      ready: false }
    The old attributes (model.oldValues)
    { _id: '55a37cc88ff0f55e6ee9be2d',
      name: 'Test 1 - 12:07:88',
      __v: 0,
      ready: true }
    ------------------