何时保存猫鼬模型

时间:2013-11-03 03:48:16

标签: node.js mongodb mongoose

这是一个架构问题。我有这样的模型:

var foo = new mongoose.Schema({
  name: String,
  bars: [{type: ObjectId, ref: 'Bar'}]
});
var FooModel = mongoose.model('Foo', foo);

var bar = new mongoose.Schema({
  foobar: String
});
var BarModel = mongoose.model('Bar', bar);

然后我想实现这样的便利方法:

BarModel.methods.addFoo = function(foo) {
  foo.bars = foo.bars || []; // Side note, is this something I should check here?
  foo.bars.push(this.id);

  // Here's the line I'm wondering about... Should I include the line below?
  foo.save();
}

我看到的最大问题是,如果我确实包含foo.save(),那么我应该将回调传递给addFoo,这样我就避免了异步操作的问题。我认为这不是更好。但是我也认为包括因为addFoo在保存之前没有真正“添加了”...会很好...我是否打破了任何设计最佳实践呢?

2 个答案:

答案 0 :(得分:1)

  

foo.bars = foo.bars || []; //旁注,这是我应该在这里查看的内容吗?

不,猫鼬会为你处理。 foo.bars最初总是一个空数组。

我认为在其他辅助方法中隐式保存是一个糟糕的设计选择。您的API受众知道他们正在制作数据库记录,他们理解save()的概念,这很简单。与mongoose的其余部分保持一致,使模型实例上的操作在内存中,直到调用显式save()为止。

但是,如果您最终在您编写的方法中执行任何I / O,则必须遵守接受回调函数的节点约定并在完成时使用error, results调用它。否则,你的应用程序会因为脆弱和竞争条件以及各种各样的肮脏而设置。

答案 1 :(得分:1)

如果添加“foo”并保存是一种常见的使用模式(并且它是处理BarModel的最后一次操作,因此不会不必要地完成多个saves),我会期望它被恰当地命名,以便它显然具有明显的副作用,如addFooAndSave。但为了与Node.JS约定保持一致,我还会添加你提到的回调(你可以把它传递给save):

BarModel.methods.addFooAndSave = function(foo, callback) {
  // foo.bars = foo.bars || []; // not needed, auto initialized to empty
  foo.bars.push(this.id);

  // Here's the line I'm wondering about... Should I include the line below?
  foo.save(callback);
}

这样你就可以打电话:

bar.addFooAndSave(function(err, bar, numAffected) { 
    // response
});

否则,如果保存不常见,我会将其作为一个明确的步骤并将“foo”添加为您拥有的方法,然后在模型实例上显式调用save