Sequelize多态多对多 - `add` mixin不起作用
Posted
技术标签:
【中文标题】Sequelize多态多对多 - `add` mixin不起作用【英文标题】:Sequelize polymorphic many to many - `add` mixin not working 【发布时间】:2022-01-23 02:14:58 【问题描述】:我有一个用于客户调查的多对多多态关联设置。我遇到的问题是在Survey
的模型实例上使用add
mixin 时。如果连接表已经有一个项目,其 surveyed
字段等于新可调查的 id
,它将被覆盖。
survey
表:
id | name |
---|---|
1 | 'Customer Survey' |
scheduled_sessions
表:
id | appointment_data |
---|---|
10 | "someData" : [] |
service_provider
表:
id | name |
---|---|
10 | Joe Doe |
survey_surveyable
表:
survey | surveyable | surveyed |
---|---|---|
1 | serviceProvider | 10 |
当我add
一个计划会话恰好与服务提供者具有相同的 id 时,连接表行被覆盖:
const surveyInstance = await DB.Survey.findByPk(1);
const scheduledSessionInstance = await DB.ScheduledSession.findByPk(10);
surveyInstance.addScheduledSession(
scheduledSessionInstance,
through: surveyable: "scheduledSession"
);
return surveyInstance.save();
这是后续运行的 SQL 查询:
SELECT "id", "name"
FROM "surveys" AS "Survey"
WHERE "Survey"."id" = 1;
SELECT "id", "appointment_data" AS "appointmentData"
FROM "scheduled_sessions" AS "ScheduledSession"
WHERE "ScheduledSession"."id" = 10;
SELECT "survey", "surveyable", "surveyed"
FROM "survey_surveyable" AS "SurveySurveyable"
WHERE
"SurveySurveyable"."survey" = 1 AND
"SurveySurveyable"."surveyed" IN (10);
UPDATE "survey_surveyable"
SET "surveyable"=$1
WHERE
"survey" = $2 AND
"surveyed" = $3
由于计划会话和服务提供者都有id=10
,连接表中的服务提供者行被覆盖导致:
survey_surveyable
表:
survey | surveyable | surveyed |
---|---|---|
1 | scheduledSession | 10 |
它应该在哪里:
survey_surveyable
表:
survey | surveyable | surveyed |
---|---|---|
1 | serviceProvider | 10 |
1 | scheduledSession | 10 |
这是一个后续问题,还是我错误地使用了add
mixin?
我的模型:
Survey.js:
module.exports = (sequelize, DataTypes) =>
class Survey extends sequelize.Sequelize.Model ;
Survey.init(
id:
type: DataTypes.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
,
name:
type: DataTypes.STRING,
allowNull: false
,
timestamps: false,
tableName: "surveys",
sequelize
);
Survey.associate = (models) =>
Survey.belongsToMany(models.ScheduledSession,
through:
model: models.SurveySurveyable,
unique: false
,
foreignKey: "survey",
constraints: false
);
;
return Survey;
;
ScheduledSession.js:
module.exports = (sequelize, DataTypes) =>
class ScheduledSession extends sequelize.Sequelize.Model ;
ScheduledSession.init(
id:
type: DataTypes.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
appointmentData:
type: DataTypes.JSONB,
allowNull: false,
field: "appointment_data"
,
paranoid: true,
tableName: "scheduled_sessions",
sequelize
);
ScheduledSession.associate = (models) =>
ScheduledSession.belongsToMany(models.Survey,
through:
model: models.SurveySurveyable,
unique: false,
scope:
surveyable: "scheduledSession"
,
foreignKey: "surveyed",
constraints: false
);
;
return ScheduledSession;
;
ServiceProvider.js:
module.exports = (sequelize, DataTypes) =>
class ServiceProvider extends sequelize.Sequelize.Model ;
ServiceProvider.init(
id:
type: DataTypes.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
name:
type: DataTypes.STRING,
allowNull: false
,
paranoid: true,
tableName: "service_provider",
sequelize
);
ServiceProvider.associate = (models) =>
ServiceProvider.belongsToMany(models.Survey,
through:
model: models.SurveySurveyable,
unique: false,
scope:
surveyable: "serviceProvider"
,
foreignKey: "surveyed",
constraints: false
);
;
return ServiceProvider;
SurveySurveyable.js:
module.exports = (sequelize, DataTypes) =>
class SurveySurveyable extends sequelize.Sequelize.Model ;
SurveySurveyable.init(
survey:
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true
,
surveyable:
type: DataTypes.STRING,
allowNull: false,
primaryKey: true
,
surveyed:
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
constraints: false
,
timestamps: false,
tableName: "survey_surveyable",
sequelize,
freezeTableName: true
);
return SurveySurveyable;
;
【问题讨论】:
【参考方案1】:您正在使用 Survey
的 mixin,但在 Survey
的关联中缺少 scope
。
Survey.associate = (models) =>
Survey.belongsToMany(models.ScheduledSession,
through:
model: models.SurveySurveyable,
unique: false,
scope: // This is missing
surveyable: "scheduledSession"
,
foreignKey: "survey",
constraints: false
);
;
【讨论】:
你是我的英雄!由于某种原因,sequelize 文档中缺少此内容。以上是关于Sequelize多态多对多 - `add` mixin不起作用的主要内容,如果未能解决你的问题,请参考以下文章