将嵌入式文档推入Mongoose中的另一个文档的过程有什么理由会剥夺该文档的方法吗?
我使用的脚本曾经可以工作,所以我不确定发生了什么变化。我知道他们在版本5中的某个时候引入了CoreMongooseArray,但是我已经恢复到5.0.7的早期版本(使用常规数组),并且问题仍然存在。
我有一个Cart模式,该模式将Cart Items嵌入一个数组中。购物车商品模式具有各种静态和实例方法。这些文件在我将文档推入购物车文档之前一直都可以使用。 那时该功能不再可用,任何尝试调用结果的错误消息均表明该功能不存在。
以下是基本架构:
购物车模式
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;
});
});
答案 0 :(得分:1)
我设法按照以下模式/模型设置顺序重现了这一点:
CartItemSchema
模式CartSchema
模式Cart
模型calculateTotals
方法添加到CartItemSchema
CartItem
模型第4步是罪魁祸首:您正在修改已经由模型(间接由Cart
使用)的模式。
正确的顺序(或至少发出最少数量问题的顺序)应为:
CartItemSchema
模式calculateTotals
方法添加到CartItemSchema
CartItem
模型CartSchema
模式Cart
模型