解决Sequelize在belongsToMany关联中的独特约束

问题描述 投票:2回答:1

我在我的项目中使用Sequelize。这是两个模型:

const User = db.define('user', {
  name: Sequelize.STRING,
  password: Sequelize.STRING
})
const Product = db.define('product', {
  name: Sequelize.STRING,
  price: Sequelize.INTEGER
})

现在用户可以购买产品,我有如下设置的关联:

Product.belongsToMany(User, {through: 'UserProducts'})
User.belongsToMany(Product, {through: 'UserProducts'})

我也有这个UserProducts表和一个额外的列。

const UserProducts = db.define('UserProducts', {
  status: Sequelize.STRING
})

Sequelize使用userId和productId的组合创建一个复合键,并且只允许一个记录结合userId和productId。因此,例如,userId 2和productId 14。

这对我来说是一个问题,因为有时人们想多次购买。我需要以下方案之一才能工作:

  1. 不要使用复合键,而是在UserProducts中使用全新的自动增量列作为键。
  2. 允许我在密钥中添加一个列,例如status,而不是单独使用userId和productId键,这样唯一键就是三者的组合。

我确实想要使用关联,因为它们提供了许多强大的方法,但是想要改变唯一键以使我能够使用相同的用户ID和产品ID组合添加多行。

由于我的模型/数据库已经运行,我将需要利用迁移来进行此更改。

对此有任何帮助,我们非常感谢。

database postgresql sequelize.js
1个回答
3
投票

当通过模型不存在主键时,Belongs-To-Many会创建一个唯一键。

由于UserProducts表中还有其他属性,因此需要为UserProducts定义模型,然后告诉sequelize使用该模型而不是创建自己的模型

class User extends Model {}
User.init({
    name: Sequelize.STRING,
    password: Sequelize.STRING
}, { sequelize })

class Product extends Model {}
ProjProductect.init({
    name: Sequelize.STRING,
    price: Sequelize.INTEGER
}, { sequelize })

class UserProducts extends Model {}
UserProducts.init({
  id: {
    type: Sequelize.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  status: DataTypes.STRING
}, { sequelize })

User.belongsToMany(Project, { through: UserProducts })
Product.belongsToMany(User, { through: UserProducts })

参考:Sequelize v4 belongsToMany

UPDATE

因为您正在使用v3并且已经为您的UserProducts表创建了一个模型,请使用以下代码段

UserProducts = db.define('UserProducts', {
  id: {
    type: Sequelize.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  status: DataTypes.STRING
})
© www.soinside.com 2019 - 2024. All rights reserved.