Sequelize - 是否可以限制结点中的记录数 table

Sequelize - is it possible to limit the number of record in junction table

有 3 table 个 student_teacherstudentteacher 具有以下关系。

每个老师负责 5 个学生,所以关系应该是一对多,但我决定创建一个联结 table 来存储这个关系的额外信息。

当我创建一个 student_teacher 记录时,有效负载将是这样的:

{
  "studentId": "xxx",
  "teacherId": "yyy",
  "groupName": "Group A"
}

假设我现在在 table student_teacher:

中有下面的记录
[
{
    "studentId": "studentA",
    "teacherId": "teacherA",
    "groupName": "Group X"
},
{
    "studentId": "studentB",
    "teacherId": "teacherA",
    "groupName": "Group X"
},
{
    "studentId": "studentC",
    "teacherId": "teacherA",
    "groupName": "Group X"
},
{
    "studentId": "studentD",
    "teacherId": "teacherA",
    "groupName": "Group X"
},
{
    "studentId": "studentE",
    "teacherId": "teacherA",
    "groupName": "Group X"
}
]

teacherA在table中已有5条记录student_teacher,我将禁止再为teacherA创建1条记录。

在Sequelize中可以实现吗?或者handle我需要在node.js函数中处理?

学生-teacher.model.js

const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;

module.exports = function (app) {
  const sequelizeClient = app.get('sequelizeClient');
  const studentTeacher = sequelizeClient.define('student_teacher', {
    id: {
      allowNull: false,
      primaryKey: true,
      type: DataTypes.UUID,
      defaultValue: Sequelize.UUIDV4,
    },
    studentId: {
      allowNull: false,
      type: DataTypes.UUID,
      references: { model: 'student', key: 'id' },
      defaultValue: Sequelize.UUIDV4,
      unique: 'studentId_foreign_idx'
    },
    teacherId: {
      allowNull: false,
      type: DataTypes.UUID,
      references: { model: 'teacher', key: 'id' },
      defaultValue: Sequelize.UUIDV4,
      unique: 'teacherId_foreign_idx'
    },
    groupName: {
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: ''
    },
    ...
  }, {
    hooks: {
      beforeCount(options) {
        options.raw = true;
      }
    }
  });

  studentTeacher.associate = function (models) {};

  return studentTeacher;
};

student.model.js

const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;

module.exports = function (app) {
  const sequelizeClient = app.get('sequelizeClient');
  const student = sequelizeClient.define('student', {
    id: {
      allowNull: false,
      primaryKey: true,
      type: DataTypes.UUID,
      defaultValue: Sequelize.UUIDV4,
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
      isEmail: true,
      unique: 'email'
    },
    firstName:{
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: '',
    },
    lastName:{
      type: DataTypes.STRING,
      allowNull: false,
      defaultValue: '',
    }
  }, {
    hooks: {
      beforeCount(options) {
        options.raw = true;
      }
    }
  });

  student.associate = function (models) {
 student.belongsToMany(models.teacher, { as: 'teachers', through: 'student_teacher', foreignKey: 'studentId', onDelete: 'cascade' })
  };

  return student;
};

teacher.model.js

const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;

module.exports = function (app) {
  const sequelizeClient = app.get('sequelizeClient');
  const teacher = sequelizeClient.define('teacher', {
    id: {
      allowNull: false,
      primaryKey: true,
      type: DataTypes.UUID,
      defaultValue: Sequelize.UUIDV4,
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
    }
  }, {
    hooks: {
      beforeCount(options) {
        options.raw = true;
      }
    }
  });

  teacher.associate = function (models) {
 teacher.belongsToMany(models.student, { as: 'students', through: 'student_teacher', foreignKey: 'teacherId', onDelete: 'cascade' })
  };

  return teacher;
};

Sequelize 的 hooks 非常符合您的要求:

// in your student-teacher.model.js model (before you return the model)

studentTeacher.beforeCreate(async (instance, options) => {
  try {
      const result = await studentTeacher.findAll({
          where: {
              teacherId: instance.teacherId
          }
      });
      if(result.length === MAX_RECORDS_FOR_TEACHER) {
          throw new Error(`Cannot create more instnaces for ${instance.teacherId}`);
      }
  }
  catch(e) {
      throw e; // You must throw an error inside the hook in order to cancel 
               // the real statement execution.
  }
});

阅读更多:https://sequelize.org/master/manual/hooks.html