You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:06:01