Sequelize - 是否可以限制结点中的记录数 table
Sequelize - is it possible to limit the number of record in junction table
有 3 table 个 student_teacher
、student
、teacher
具有以下关系。
每个老师负责 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.
}
});
有 3 table 个 student_teacher
、student
、teacher
具有以下关系。
每个老师负责 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.
}
});