在Mongoose中将EmbeddedDoc推送到另一个文档中的过程会剥夺该文档的方法吗?
我使用的脚本以前是有效的,所以我不确定发生了什么变化。我知道他们在版本5的某个时候引入了CoreMongooseArray,但我已经恢复到5.0.7的早期版本(使用普通数组(,问题仍然存在。
我有一个Cart模式,它将Cart项目嵌入到一个数组中。购物车项目模式有各种静态方法和实例方法。在我将文档推入Cart文档之前,这些都是完全可用的。此时,该函数不再可访问,任何调用该函数的尝试都会导致该函数不存在的错误消息。
以下是基本模式:
CART模式
let mongoose = require('mongoose'),
Schema = mongoose.Schema;
let idvalidator = require('mongoose-id-validator');
let CartItemSchema = require('./CartItem');
let PromotionSchema = require('./Promotion');
let _ = require('lodash');
let CartSchema = new Schema({
customer_id: {
type: Schema.Types.ObjectId,
ref: 'User'
},
cartItems: [CartItemSchema],
customItems: [],
promotionItems: [{type: PromotionSchema, excludeIndexes: true}],
quantity: {
type: Number,
min: 0,
required: true,
default: 0
},
subtotal: {
type: Number,
min: 0,
required: true,
default: 0
},
subtotalWithoutTax:{
type: Number,
min: 0,
required: true,
default: 0
},
total: {
type: Number,
min: 0,
required: true,
default: 0
},
totalWithoutTax:{
type: Number,
min: 0,
required: true,
default: 0
}
},
{
timestamps: true,
id: false
}
);
CartSchema.index({ createdAt: 1 }, { expireAfterSeconds: 604800 });
CartSchema.virtual('discount').get(function(){
return _.round(this.subtotal - this.total, 2);
});
CartSchema.virtual('tax').get(function(){
return _.round(this.total - this.totalWithoutTax, 2);
});
CartSchema.set('toObject', {virtuals: true});
CartSchema.set('toJSON', {virtuals: true});
CartSchema.plugin(idvalidator);
module.exports = CartSchema;
购物车项目架构
let mongoose = require('mongoose'),
Schema = mongoose.Schema;
let idvalidator = require('mongoose-id-validator');
let SizeSchema = require('./Size');
let ProductExtraSchema = require('./ProductExtra');
let CartItemSchema = new Schema({
product_id: {
type: Schema.Types.ObjectId,
ref: 'Product',
required: true
},
sku: {
type: String,
required: true,
trim: true,
lowercase: true
},
name: {
type: String,
required: true,
trim: true
},
description: {
type: String,
trim: true,
alias: "desc"
},
price: {
type: Number,
min: 0,
required: true,
default: 0
},
priceWithoutTax:{
type: Number,
min: 0,
required: true,
default: 0
},
total: {
type: Number,
min: 0,
required: true,
default: 0
},
totalWithoutTax:{
type: Number,
min: 0,
required: true,
default: 0
},
taxable: {
type: Boolean,
required: true,
default: false
},
taxRate: {
type: Number,
required: true,
min: 0,
default: 0.2
},
quantity: {
type: Number,
min: 1,
required: true,
default: 1
},
size: SizeSchema,
extras: [ProductExtraSchema]
},
{
timestamps: true,
id: false
}
);
CartItemSchema.set('toObject', {virtuals: true});
CartItemSchema.set('toJSON', {virtuals: true});
CartItemSchema.plugin(idvalidator);
module.exports = CartItemSchema;
这些模型在一个单独的脚本中转换为模型,其中添加了静态模型和实例模型。
如果我然后做以下操作,方法会在推送发生后立即消失:
let CartItem = require('../models/CartItem');
let Cart = require('../models/Cart');
let cartItem = CartItem.hydrate(req.body.cartItem);
let cart = new Cart();
console.log(cartItem.calculateTotals);
cart.cartItems.push(cartItem);
console.log(cart.cartItems[0].calculateTotals);
// Console.logs([Function])
// Console.logs(undefined)
更糟糕的是,我创建了一个非常基本的摩卡测试,它基本上做了同样的事情,并且成功了。那么,有什么区别呢?为什么一个成功了而另一个没有成功?
describe('test', function(){
it('should allow childs methods to be accessed', function(){
let childSchema = new Schema({
name: String
},
{
timestamps: true,
id: false
}
);
childSchema.methods.hyper = function(){
console.log("I've eaten too many sweets")
};
let parentSchema = new Schema({
name: String,
children: [childSchema],
},
{
timestamps: true,
id: false
}
);
let parent = mongoose.model('Parent', parentSchema);
let child = mongoose.model('Child', childSchema);
let c = child.hydrate({name: 'Sarah'});
let p = new parent({name: 'Joe'});
p.children.push(c);
for(let c of p.children){
c.hyper();
// Successfully logs "I've eaten too many sweets"
}
return true;
});
});
我使用以下模式/模型设置顺序成功地再现了这一点:
- 创建
CartItemSchema
模式 - 创建
CartSchema
模式 - 创建
Cart
模型 - 将
calculateTotals
方法添加到CartItemSchema
- 创建
CartItem
模型
步骤#4是罪魁祸首:您正在修改一个模型(间接地,由Cart
(已经使用的模式。
正确的订单(或者至少是产生最少问题的订单(应该是:
- 创建
CartItemSchema
模式 - 将
calculateTotals
方法添加到CartItemSchema
- 创建
CartItem
模型 - 创建
CartSchema
模式 - 创建
Cart
模型