【问题标题】:Mongoose schema/methods disappearing when overwriting subdocument覆盖子文档时猫鼬模式/方法消失
【发布时间】:2013-12-21 04:17:01
【问题描述】:

我有一个带有方法的架构 - 2 种变体。它们在第一次添加地址时都可以正常工作,但是在添加另一个地址时(即当它通过 for 循环时),第一个版本会崩溃。我所说的炸毁的意思是它似乎破坏了我的订单实例 - 没有更多的“保存”方法。

架构

var Address = new Schema({
  type: { type: String, enum: ['shipping', 'billing'] },
  street: { type: String, required: true },
  city: { type: String, required: true },
  region: String,
  country: String,
  postal: { type: String, required: true },
});

var Order = new Schema({
  email: {
    type: String
  },
  address: [Address]
});

现在,如果我在我的架构中添加了 addAddress() 方法。这是我尝试过的 2 个版本。

// Version 1 - has issues on subsequent call
Order.methods.addAddress = function() {

  var data = { type: 'shipping', city: 'Tempe', postal: '85281', street: '420 Mill Ave'};

  for(var i = this.address.length-1; i >=0; i--) {
    if(this.address[i].type === type) {
     delete address[i];   
    }
  }
  this.address.push(data);
}

// Version 2 - works fine
Order.methods.addAddress = function() {

  var data = { type: 'shipping', city: 'Tempe', postal: '85281', street: '420 Mill Ave'};

  var found = false;
  for(var i = this.address.length-1; i >=0; i--) {
    if(this.address[i].type === type) {
      found = true;
      this.address[i] = data;
    }
  }
  if(!found)
    this.address.push(data);
}

在使用 V1 后尝试保存会产生此错误:

Uncaught Exception
TypeError: Object #<Object> has no method 'save'
    at /var/node_modules/mongoose/lib/document.js:1270:13
    at Array.forEach (native)
    at model.pre.err.stack (/var/node_modules/mongoose/lib/document.js:1252:12)
    at model._next (/var/node_modules/mongoose/node_modules/hooks/hooks.js:50:30)
    at model.proto.(anonymous function) [as save] (/var/node_modules/mongoose/node_modules/hooks/hooks.js:96:20)
    at Promise.<anonymous> (/var/controllers/cart.js:79:11)
    at Promise.<anonymous> (/var/node_modules/mongoose/node_modules/mpromise/lib/promise.js:171:8)
    at Promise.EventEmitter.emit (events.js:95:17)
    at Promise.emit (/var/node_modules/mongoose/node_modules/mpromise/lib/promise.js:88:38)
    at Promise.fulfill (/var/node_modules/mongoose/node_modules/mpromise/lib/promise.js:101:20)

让我们看下面的代码:

Order.findById(id.exec(function(err, o) {
  o.addAddress('shipping', { street: '1000 Mill Ave', city: 'Tempe', postal: '85281' });
  console.log(o);
  o.save(function(err, order) {
  });
})

注意到控制台调用了吗?在每个变体中,订单对象似乎都可以:

{
  _id: 007d0000b10000000000000c,
  address: [{
    street: '420 Mill Ave',
    postal: '85281',
    city: 'Tempe',
    type: 'shipping'
    _id: 52b2459f1547a5e12300000b
  }]
}

但它似乎丢失了诸如“保存”方法之类的东西。

有什么想法吗?

【问题讨论】:

    标签: javascript mongoose


    【解决方案1】:

    您将地址定义为字典而不是地址对象。相反,您应该这样做:

    Order.methods.addAddress = function(type, data, next) {
    
        // Have your removal code here
    
        var self = this
        var address = new Address(data)
        address.save(function(err, address) {
            if (err) {
                ...
            } else {
                self.address.push(address)
                next()
            }
        })
    }
    

    请注意,我正在根据架构定义使用地址对象填充地址数组。

    【讨论】:

    • 问题是它可以像使用字典一样正常工作。 Tt 删除它会破坏内部的某些东西。部分问题可能是我使用删除而不是切片并离开..你怎么称呼它..空的腐烂的物体外壳,所以当地址长度为 2 但索引 0 处没有任何内容时,Mongoose 可能会吓坏
    • 是的,您的假设可能是正确的。从循环中的数组中删除内容总是一个问题。尝试使用 this.address[i].delete() 删除数组中的对象,使用 foreach 和/或将要保存的地址添加到可以覆盖旧数据的新数组中,this.address = newArray,试图消除数组索引问题。
    • 噢,我什至没想到我的子文档会有 delete()!
    • 有点——它是 remove() 而不是 delete()。所以是的,使用删除以及拼接工作 - 删除地址[i] 会弄得一团糟。这个问题完全与弄乱索引有关。没想到它会像那样炸毁猫鼬!
    • @Yashua 如果有帮助,您介意将其标记为正确的解决方案吗?
    猜你喜欢
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 2015-02-12
    • 2017-06-01
    • 1970-01-01
    • 2015-06-26
    • 2015-10-01
    • 1970-01-01
    相关资源
    最近更新 更多