【发布时间】:2017-09-23 00:04:06
【问题描述】:
如果我在将文档发送到客户端之前获取并填充它,那么在进行更新时取消填充这些字段的最佳方法是什么?
模式:
var User = new mongoose.Schema({
name: String
});
var Post = new mongoose.Schema({
title: String,
likes: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}]
});
控制器:
app.get('/post/:id', function (req, res, next) {
Post.findById(req.params.id).populate('likes').exec(function (err, post) {
if (err) return next(err);
res.json(post);
});
});
app.put('/post/:id', function (req, res, next) {
Post.findById(req.params.id, function (err, post) {
if (err) return next(err);
_.extend(post, req.body);
post.save(function (err) {
if (err) return next(err);
res.json(post);
});
});
});
所以在客户端我收到类似的东西:
{
_id: 123,
title: 'Test post',
likes: [{
_id: 456,
name: 'John Doe'
}, {
_id: 789,
name: 'Max Danger'
}]
}
这一切都很好。但是当我在客户端修改模型(我使用Backbone.Marionette FWIW),然后将其保存回来时,Mongoose 会抛出Cast to ObjectId failed for value "[object Object],456" at path "likes" 错误。
我认为 Mongoose 能够自动从这些对象中抓取 _ids,但它似乎不是那样工作的......?
那么这里最好的方法是什么?在发送到服务器之前,我应该在客户端上提取 ID 吗?还是我在调用 save 之前先在服务器上拔?
另外,保存后我需要重新填充这些字段,然后再将保存的产品再次发送回客户,对吗?
最后,我认为我不能实际上使用 Mongoose 的 depopulate() 方法,因为我只有从客户端接收到的 JSON,而不是实际的 Model 实例。
任何帮助..?谢谢!
【问题讨论】:
-
您可以使用Mongoose' middleware 在保存文档之前从 JSON 中删除这些属性,
schema.pre('save', function (next) {...})否则如果添加到客户端上的数组仅在更新时发送 id 数组 -
谢谢,我想我曾经尝试过,而且我认为它有效。我想我只是希望我错过了 Mongoose 中会自动获取 ID 的东西。另外,使用预保存钩子不适用于实例化新模型,这有时也是我的情况。这意味着客户端将完整的对象发送到 POST 处理程序,并且 POST 处理程序使用
new Model(req.body)进行实例化。如果我不先提取 ID,它会在实例化时失败。所以也许客户端采摘对这两种情况都是最有意义的。谢谢。
标签: node.js backbone.js express mongoose marionette