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
  });
};