猫鼬嵌入式文档,方法"is not a function"



在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;
});
});

我使用以下模式/模型设置顺序成功地再现了这一点:

  1. 创建CartItemSchema模式
  2. 创建CartSchema模式
  3. 创建Cart模型
  4. calculateTotals方法添加到CartItemSchema
  5. 创建CartItem模型

步骤#4是罪魁祸首:您正在修改一个模型(间接地,由Cart(已经使用的模式。

正确的订单(或者至少是产生最少问题的订单(应该是:

  1. 创建CartItemSchema模式
  2. calculateTotals方法添加到CartItemSchema
  3. 创建CartItem模型
  4. 创建CartSchema模式
  5. 创建Cart模型

相关内容

最新更新