Sequelize 多态多对多 - `add` mixin 不工作
Sequelize polymorphic many to many - `add` mixin not working
我有一个用于客户调查的多对多多态关联设置。我遇到 运行 的问题是在 Survey
的模型实例上使用 add
mixin 时。如果加入 table 已经有一个 surveyed
字段等于新可调查对象的 id
的项目,它将被覆盖。
survey
table:
id
name
1
'Customer Survey'
scheduled_sessions
table:
id
appointment_data
10
{ "someData" : [] }
service_provider
table:
id
name
10
Joe Doe
survey_surveyable
table:
survey
surveyable
surveyed
1
serviceProvider
10
当我 add
安排的会话恰好与服务提供商具有相同的 ID 时,连接 table 行被覆盖:
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"=
WHERE
"survey" = AND
"surveyed" =
由于计划的会话和服务提供商都有 id=10
,连接 table 中的服务提供商行被覆盖,导致:
survey_surveyable
table:
survey
surveyable
surveyed
1
scheduledSession
10
它应该在的地方:
survey_surveyable
table:
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;
};
您正在使用 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
});
};
我有一个用于客户调查的多对多多态关联设置。我遇到 运行 的问题是在 Survey
的模型实例上使用 add
mixin 时。如果加入 table 已经有一个 surveyed
字段等于新可调查对象的 id
的项目,它将被覆盖。
survey
table:
id | name |
---|---|
1 | 'Customer Survey' |
scheduled_sessions
table:
id | appointment_data |
---|---|
10 | { "someData" : [] } |
service_provider
table:
id | name |
---|---|
10 | Joe Doe |
survey_surveyable
table:
survey | surveyable | surveyed |
---|---|---|
1 | serviceProvider | 10 |
当我 add
安排的会话恰好与服务提供商具有相同的 ID 时,连接 table 行被覆盖:
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"=
WHERE
"survey" = AND
"surveyed" =
由于计划的会话和服务提供商都有 id=10
,连接 table 中的服务提供商行被覆盖,导致:
survey_surveyable
table:
survey | surveyable | surveyed |
---|---|---|
1 | scheduledSession | 10 |
它应该在的地方:
survey_surveyable
table:
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;
};
您正在使用 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
});
};