Javascript 如何在查询中通过表获取属性?
我在做一个简单的购物车。我有一个购物车模型,一个产品模型和一个表CartItems。这些是协会:Javascript 如何在查询中通过表获取属性?,javascript,node.js,sequelize.js,Javascript,Node.js,Sequelize.js,我在做一个简单的购物车。我有一个购物车模型,一个产品模型和一个表CartItems。这些是协会: models.Cart.belongsToMany(models.Product, { through: 'CartItems', as: 'items' }) models.Product.belongsToMany(models.Cart, { through: "CartItems" }); 以下是模型的定义: 购物车型号 var Cart = sequelize.define('Cart'
models.Cart.belongsToMany(models.Product, { through: 'CartItems', as: 'items' })
models.Product.belongsToMany(models.Cart, { through: "CartItems" });
以下是模型的定义:
购物车型号
var Cart = sequelize.define('Cart', {
userId: {
allowNull: false,
type: Sequelize.INTEGER,
references: {
model: 'User',
key: 'id',
},
},
totalPrice: DataTypes.FLOAT
});
var Product = sequelize.define('Product', {
code: DataTypes.STRING,
name: DataTypes.STRING,
price: DataTypes.FLOAT
});
产品型号
var Cart = sequelize.define('Cart', {
userId: {
allowNull: false,
type: Sequelize.INTEGER,
references: {
model: 'User',
key: 'id',
},
},
totalPrice: DataTypes.FLOAT
});
var Product = sequelize.define('Product', {
code: DataTypes.STRING,
name: DataTypes.STRING,
price: DataTypes.FLOAT
});
CartItems型号
在这个模型中,我添加了一个quantity和price属性,因为我在某个地方读到,有一个他们下订单时价格的历史记录是很好的。还有quantity属性,因为我只想在添加另一个产品时更改数量,而不是添加另一行
var CartItem = sequelize.define('CartItem', {
CartId: DataTypes.INTEGER,
ProductId: DataTypes.INTEGER,
quantity: DataTypes.INTEGER,
price: DataTypes.FLOAT
});
我知道这可能不是做事情的最佳方式,但即使我更改了实现,我也想知道:如何访问through表中的属性
具体而言,我尝试对签出功能执行以下操作:
Cart.prototype.checkout = async function () {
let cartItemArray = await this.getItems({
include: [{
model: Product,
through: {
attributes: ['quantity'],
}
}]
});
cartItemArray = cartItemArray.map((item) => {
return {
code: item.code,
price: item.price,
quantity: item.quantity
};
});
let total = getTotalPrice(cartItemArray);
return total;
};
首先是一些警告
警告1。您的产品
型号和CartItem
型号中都有一个价格
字段。你确定要这个吗?在您尝试编写checkout()
方法时,当您执行item.price
时,您希望获得哪些价格?我的直觉告诉我,你并不真的想拥有两个字段,但是如果你真的想这样做,考虑重新命名其中一个以避免歧义。
警告2。您的购物车中有一个总价
。。。该字段是否应该跟踪相关产品的价格总和?如果是,这是一个坏主意,请将该字段全部删除,并且在需要求和时,立即计算该字段,因为这样保存重复数据非常容易出错(您必须确保它们是同步的)
错误1
您使用以下代码明确定义了连接表模型,即CartItem
:
var CartItem = sequelize.define('CartItem', { /* ... */ });
到目前为止还不错。但是当你定义多对多关系时,你犯了一个错误。您通过“CartItems”
使用了,但您应该通过“CartItem”
使用。实际上,这种情况下的最佳实践是直接引用模型,因为您有:到:CartItem
。由于这个原因,Sequelize最终忽略了您的模型并自动创建了一个连接表,而没有额外的字段price
和quantity
错误2
在尝试编写checkout()
方法时,您执行了以下操作:
this.getItems({
include: [{
model: Product,
through: {
attributes: ['quantity'],
}
}]
});
这是没有道理的。回想一下,项
只是为产品
设置的别名。运行此代码会产生SequelizeAgerLoadingError:产品与产品不关联代码>
相反,您只需执行this.getItems()
,而无需任何参数
错误3
接下来,您编写了代码:
return {
code: item.code,
price: item.price,
quantity: item.quantity
};
这表明您希望quantity
作为code
旁边的另一个字段出现。这是不正确的<代码>代码
是来自产品
模型的字段,数量
是来自CartItem
模型的字段。Sequelize不会像这样“展平”它们。相反,关联本身的字段嵌套在查询结果中,如下所示:
{
"id": 1,
"code": null,
"name": "test",
"price": null,
"createdAt": "2018-03-11T19:11:12.862Z",
"updatedAt": "2018-03-11T19:11:12.862Z",
"CartItem": {
"CartId": 1,
"ProductId": 1,
"quantity": 2,
"price": 1.5,
"createdAt": "2018-03-11T19:11:13.047Z",
"updatedAt": "2018-03-11T19:11:13.047Z"
}
}
因此,您应该使用item.CartItem.quantity
,而不是那里的item.quantity
总结
标题“如何在查询中从through表中获取属性?”中的问题的答案是“只需执行查询,即在您的情况下,this.getItems()
,因为through表中的属性默认会出现在结果中”
只是你犯了一些其他的错误,当然,它不起作用。有价格历史记录很好,但你不需要根据数量更新价格。你应该把它和数量相乘得到它。如果有折扣的话,把它也放在那张表上。所以你可以稍后再看。