1

主要目标:

在调用路由时,我要么得到一个新的,要么更新现有的 CartItem 对象。对象数量和总计在中间件中传递,因此对象总计被重新计算。

Schema 似乎在第一个请求上正确地应用了它的中间件(基于控制台日志)。

但是,如果我发出另一个 http 请求,我只会得到一个更新总数的对象。

这超出了我的理解,我将不胜感激。

架构:

const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');
const Product = require('./Product');
const Cart = require('./Cart');
const refIsValid = require('../middleware/refIsValid');

const cartItemSchema = mongoose.Schema({
    name: { type: String },
    productRef: { type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true },
    cartRef: { type: mongoose.Schema.Types.ObjectId, ref: 'Cart', required: true },
    price: { type: Number, default: 0 },
    imgUrl: { type: String },
    amount: { type: Number, required: true },
    total: { type: Number, default: 0 },
    active: { type: Boolean, default: true },
    uniqueName: { type: String, unique: true },
});

cartItemSchema.path('productRef').validate((value, respond) => {
    return refIsValid(value, respond, Product);
}, 'Invalid product ref.');

cartItemSchema.path('cartRef').validate((value, respond) => {
    return refIsValid(value, respond, Cart);
}, 'Invalid cart ref.');

cartItemSchema.path('price').get(function(num) {
    return num.toFixed(2);
});

cartItemSchema.pre('save', async function(next) {
    const refCart = await Cart.findById(this.cartRef).lean().exec();
    const refProduct = await Product.findById(this.productRef).lean().exec();
    const uniqueName = `${refProduct._id}_${refCart._id}`;

    this.name = refProduct.name;
    this.price = refProduct.price;
    this.imgUrl = refProduct.imgUrl;
    this.total = (this.price * this.amount).toFixed(2);
    this.uniqueName = uniqueName;
    next();
});

cartItemSchema.post('findOneAndUpdate', async function(result) {
    console.log('TCL: result', result);

    await result.save(function(err) {
        if (err) {
            console.error('ERROR!');
        }
    });
    console.log('TCL: docToUpdate', result);
});

cartItemSchema.plugin(uniqueValidator);

module.exports = mongoose.model('cartItem', cartItemSchema);

控制器:

    static async updateOrCreate(req, res, next) {
    try {
        let { cartRef, productRef, amount } = req.body;
        let options = { upsert: true, new: true, setDefaultsOnInsert: true };
        // const uniqueName = `${productRef._id}_${cartRef._id}`;

        const updateOrCreate = await CartItem.findOneAndUpdate(
            { cartRef: cartRef, productRef: productRef },
            { amount: amount },
            options,
        );
        if (updateOrCreate) {
            const result = await CartItem.findById(updateOrCreate._id);
            console.log('TCL: CartItemController -> updateOrCreate -> result', result);

            res.status(200).json({
                isNew: false,
                message: 'item updated',
                productItem: result,
            });
            return;
        }
    } catch (error) {
        error.statusCode = 500;
        next(error);
    }
}
4

0 回答 0