NodeJS+Sequelize如何使用自定义关联模型获取中间表额外字段
Sequelize多对多关联返回中间表自定义字段解决方案
核心问题梳理
你当前配置存在3个问题导致无法获取中间表自定义字段:
- 关联定义时
through参数传入表名字符串,Sequelize会自动生成默认中间表模型,不会使用你自定义的关联模型 - 多对多关联的
foreignKey配置写反,且关联模型内部重复定义关联时引用了不存在的变量 - 查询时未指定需要返回中间表的自定义字段
分步修改方案
1. 修正入口文件的模型引入与关联定义(index.js)
首先需要引入你自定义的关联模型,关联时through参数直接传入模型实例而非表名字符串,同时修正外键配置:
const dbConfig = require("../config/db.config.js"); const Sequelize = require("sequelize"); const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, { host: dbConfig.HOST, dialect: dbConfig.dialect, operatorsAliases: false, pool: { max: dbConfig.pool.max, min: dbConfig.pool.min, acquire: dbConfig.pool.acquire, idle: dbConfig.pool.idle } }); const db = {}; db.Sequelize = Sequelize; db.sequelize = sequelize; // 先引入所有模型,包括关联模型 db.projects = require("./project.model.js")(sequelize, Sequelize); db.users = require("./user.model.js")(sequelize, Sequelize); db.userProjects = require("./userProject.model.js")(sequelize, Sequelize); // 引入自定义关联模型 // 修正关联定义,through传入模型实例,外键对应正确 db.projects.belongsToMany(db.users, { through: db.userProjects, // 此处传入模型而非字符串 as: "users", foreignKey: "project_id", // 项目表在中间表的外键是project_id }); db.users.belongsToMany(db.projects, { through: db.userProjects, as: "projects", foreignKey: "user_id", // 用户表在中间表的外键是user_id }); // 如果你是Employee+Office场景,关联写法参考: // db.Employee.belongsToMany(db.Office, { // through: db.EmployeeOffice, // as: 'offices', // foreignKey: 'employee_id' // }) // db.Office.belongsToMany(db.Employee, { // through: db.EmployeeOffice, // as: 'employees', // foreignKey: 'office_id' // }) module.exports = db;
2. 清理关联模型的冗余错误代码
删除UserProject.js/EmployeeOffice.js中冗余的关联定义,避免循环依赖:
module.exports = (sequelize, Sequelize) => { const UserProject = sequelize.define('user_project', { user_id: { type: Sequelize.INTEGER, references: { model: 'users', key: 'id' } }, project_id: { type: Sequelize.INTEGER, references: { model: 'projects', key: 'id' } }, user_type: { // 对应Office场景的employee_chair字段 type: Sequelize.INTEGER, } }, { timestamps: false, tableName: 'users_projects' }); // 删掉原来这里的两行错误的belongsToMany定义 return UserProject; };
3. 修正查询配置,指定返回中间表字段
在include中添加through配置,指定需要返回的中间表字段,还可以通过as自定义中间表的返回键名:
const { Op } = require("sequelize"); const db = require("../models"); const Project = db.projects; // Retrieve all Projects from the database. exports.findAll = (req, res) => { const title = req.query.title; var condition = title ? { title: { [Op.like]: `%${title}%` } } : null; Project.findAll({ where: condition, include: [ { model: db.users, as: "users", through: { as: "user_project", // 自定义中间表返回的键名,Office场景可设为"employee_office" attributes: ["user_type", "createdAt", "updatedAt"] // 指定要返回的中间表字段 } }] }) .then(data => { res.send(data); }) .catch(err => { res.status(500).send({ message: err.message || "Some error occurred while retrieving projects." }); }); }; // Office场景查询写法参考: // Office.findAll({ // include: [{ // model: Employee, // as: 'employees', // through: { // as: 'employee_office', // attributes: ['employee_chair', 'createdAt', 'updatedAt'] // } // }] // })
修改完成后重启服务即可返回包含中间表自定义字段的结果,和你预期的返回格式完全一致。
内容的提问来源于stack exchange,提问作者David Encina Martínez
相关产品推荐
相关产品推荐

