如何使用两个关联模型的Mixin创建订单项?
关于同时通过Order和Product关联创建订单项的问题
我需要通过Product和Order两个关联模型创建订单项:Order与Product和订单项均为一对多关系,订单项同时属于Product和Order。
目前已实现两种单独创建订单项的方式:
- 通过
Product的Mixin创建,传入order_id:
product.createOrderItem({ order_id: order.id, quantity, amount: product?.price * quantity, currency: 'SAR' });
- 通过
Order的Mixin创建,传入产品ID(代码中为local_product_id):
const order = await user?.createOrder({ status: 'Processing', source: 'manual' }); const orderItemsPromises = products?.map(async ({ productId, quantity }) => { const product = await Product.findByPk(productId); if (product) { return order.createOrderItem({ local_product_id: product.id, quantity, amount: product?.price * quantity, currency: 'SAR' }); } return null; });
想请教:能不能同时使用两个模型的关联(即两者的Mixin)来创建订单项?
解答
没必要同时调用两个模型的Mixin来创建订单项。不管是从Order还是Product侧调用关联创建方法,本质都是向订单项表插入一条包含order_id和product_id的记录,只要这两个字段正确传入,就能完成订单项的创建。
如果非要通过这种方式实现(比如想触发两边关联的钩子或验证逻辑),可以先通过其中一方创建订单项,再通过另一方的关联进行绑定,但这属于冗余操作,完全没必要。
性能优化建议
当前代码存在N+1查询问题(循环调用findByPk),可以改成批量查询产品再创建订单项,提升性能:
// 先批量查询所有需要的产品 const productIds = products?.map(item => item.productId); const foundProducts = await Product.findAll({ where: { id: productIds } }); // 用Map存产品,方便快速查找 const productMap = new Map(foundProducts.map(p => [p.id, p])); // 创建订单 const order = await user?.createOrder({ status: 'Processing', source: 'manual' }); // 批量创建订单项 const orderItemsPromises = products?.map(({ productId, quantity }) => { const product = productMap.get(productId); if (!product) return null; return order.createOrderItem({ local_product_id: product.id, quantity, amount: product.price * quantity, currency: 'SAR' }); }); // 等待所有订单项创建完成 await Promise.all(orderItemsPromises.filter(p => p !== null));
你也可以利用Sequelize的嵌套创建能力,在创建订单的同时直接创建关联的订单项:
const productIds = products?.map(item => item.productId); const foundProducts = await Product.findAll({ where: { id: productIds } }); const productMap = new Map(foundProducts.map(p => [p.id, p])); // 整理订单项数据 const orderItems = products?.map(({ productId, quantity }) => { const product = productMap.get(productId); return product ? { local_product_id: product.id, quantity, amount: product.price * quantity, currency: 'SAR' } : null; }).filter(item => item !== null); // 创建订单并同时创建订单项 const order = await user?.createOrder({ status: 'Processing', source: 'manual', orderItems // 这里要和Order模型中OrderItem的关联别名一致 }, { include: [{ model: OrderItem, as: 'orderItems' }] });
总结:单从Order或Product侧调用关联创建方法就足够完成订单项的创建,无需同时使用两个Mixin。优化查询逻辑能大幅提升代码性能。
内容的提问来源于stack exchange,提问作者Ali Hassan
相关产品推荐
相关产品推荐

