简体   繁体   English

Sequelize Mysql - 无法插入具有一对多关系的 model

[英]Sequelize Mysql - Unable to Insert model with one to many relationship

Design Overview: I've an application with Invoice creation and Inventory management features in it. Design Overview:我有一个具有发票创建和库存管理功能的应用程序。 Let's first understand the database design with 2 entities that we have as below:让我们首先了解具有以下两个实体的数据库设计:

  1. Invoices发票
  2. Items项目

Now, here I've a M:N relationship between these 2 entities because one invoice can contain multiple items and one item can be included in many such invoices.现在,我在这两个实体之间建立了 M:N 关系,因为一张发票可以包含多个项目,并且一个项目可以包含在许多这样的发票中。

So, I've created a 3rd table which we call joining table to associate these entities as shown in the image below,所以,我创建了第三个表,我们称之为连接表来关联这些实体,如下图所示,

数据库设计img

Problem Statemet: I'm unable to insert model in the child table(invoice_items) using include attribute. Problem Statemet:我无法使用 include 属性在子表 (invoice_items)中插入 model。 Look at the code below to understand what's wrong happening here?查看下面的代码以了解这里发生了什么问题?

3 Model Classes as below: 3 Model 类如下:

1. Invoice:一、发票:

Note: Providing with fewer attributes to keep it short. Note:提供较少的属性以使其简短。

 module.exports = (sequelize, DataTypes) => { const Invoice = sequelize.define('Invoice', { invoiceId: { type: DataTypes.INTEGER.UNSIGNED, allowNull: false, autoIncrement: true, primaryKey: true }, invoiceNumber: { type: DataTypes.INTEGER(6).UNSIGNED.ZEROFILL, allowNull: false, unique: true }, invoiceTotal: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0.00 }, paymentTotal: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0.00 }, invoiceDate: { type: DataTypes.DATEONLY, defaultValue: DataTypes.NOW, allowNull: false } }, { underscored: true }); Invoice.associate = function (model) { Invoice.belongsTo(model.Customer, { as: 'customer', foreignKey: { name: "cust_id", allowNull: false } }); // association with 3rd table Invoice.hasMany(model.InvoiceItem, { as: 'invoice_item', constraints: true, onDelete: 'NO ACTION', foreignKey: { name: "invoice_id", allowNull: false } }); }; return Invoice; }

2. Item: 2.项目:

Note: Providing with fewer attributes to keep it short. Note:提供较少的属性以使其简短。

 module.exports = (sequelize, DataTypes) => { const Item = sequelize.define('Item', { itemId: { type: DataTypes.INTEGER.UNSIGNED, allowNull: false, autoIncrement: true, primaryKey: true }, itemName: { type: DataTypes.TEXT, allowNull: false, defaultValue: '' }, // this is a opening stock quantityInStock: { type: DataTypes.INTEGER.UNSIGNED, allowNull: false, defaultValue: 0, }, unitPrice: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0.00 } }, { underscored: true }); Item.associate = function (model) { // association with 3rd table Item.hasMany(model.InvoiceItem, { as: 'invoice_item', // alias name of a model constraints: true, onDelete: 'NO ACTION', foreignKey: { name: "item_id", allowNull: false } }); }; return Item; }

3. Invoice_Item: 3.发票项目:

Note: Providing with fewer attributes to keep it short. Note:提供较少的属性以使其简短。

 module.exports = (sequelize, DataTypes) => { const InvoiceItem = sequelize.define('InvoiceItem', { invoiceItemId: { type: DataTypes.INTEGER.UNSIGNED, allowNull: false, autoIncrement: true, primaryKey: true }, quantity: { type: DataTypes.INTEGER.UNSIGNED, allowNull: false, defaultValue: 0, }, rate: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0.00 } }, { underscored: true }); InvoiceItem.associate = function(model) { InvoiceItem.belongsTo(model.Invoice, { as: 'invoice', foreignKey: { name: "invoice_id", allowNull: false } }); InvoiceItem.belongsTo(model.Item, { as: 'item', foreignKey: { name: "item_id", allowNull: false } }); } return InvoiceItem; }

Now, I'm using below code to create an invoice with the list of items in it.现在,我正在使用下面的代码创建一个包含项目列表的发票。 But, this is not inserting the child records in the joining table( invoice_items ).但是,这并不是在连接表 ( invoice_items ) 中插入子记录。 What's wrong here in the code below?下面的代码有什么问题?

 invoice = await Invoice.create({ "invoiceNumber": req.body.invoiceNumber, "invoiceDate": req.body.invoiceDate, "invoiceTotal": req.body.invoiceTotal, "paymentTotal": req.body.paymentTotal, "cust_id": req.body.customer.custId, invoice_items: [{ item_id: 1, quantity: 2, rate: 300 }] }, { include: [{ association: InvoiceItem, as: 'invoice_item' }] });

After trying so many variations, I understand that there was a problem in the association of my model classes.在尝试了这么多变化之后,我了解到我的 model 类的关联存在问题。 And, below is the way of associating both Invoice and Item model classes for M:N(Many to Many) relationships.并且,下面是将InvoiceItem model 类关联为 M:N(多对多)关系的方式。 I can now update the join table(invoice_items) by inserting the record in it for each invoice we create in the system with the items in it.我现在可以更新连接表 (invoice_items),方法是为我们在系统中创建的每张发票插入记录,其中包含项目。

 Invoice.associate = function (model) { // association in Invoice model class Invoice.belongsToMany(model.Item, { through: 'InvoiceItem', constraints: true, onDelete: 'NO ACTION', foreignKey: { name: "invoice_id", // foreign key column name in a table invoice_items table allowNull: false } }); };

 Item.associate = function (model) { // association in Item model class Item.belongsToMany(model.Invoice, { through: 'InvoiceItem', constraints: true, onDelete: 'NO ACTION', foreignKey: { name: "item_id", // foreign key column name in a table invoice_items allowNull: false } }); };

Create Invoice with Items in it:创建包含项目的发票:

Note: Passing itemId (1) as a parameter in the addItems() method. Note:将 itemId (1) 作为参数传递到 addItems() 方法中。 If you have multiple items in an invoice then you can add forEach loop here to iterate over each item and individually pass the itemId , quantity and rate for an item sold to the customer.如果您在一张发票中有多个项目,那么您可以在此处添加forEach循环以遍历每个项目,并分别传递销售给客户的项目的itemIdquantityrate

 // first create the invoice invoice = await Invoice.create(invoice); // Next, add record in the join table await invoice.addItems([1], { through: { quantity: item.quantity, rate: item.rate } });

Database Tables with one Test Result:具有一个测试结果的数据库表:

1. Invoice Table: 1. 发票表:

发票表

2. Invoice_items Table(Join Table): 2. Invoice_items 表(连接表):

发票项目表

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM