Feathers-Sequelize hasMany关联仅返回首个结果且结构扁平化求助
解决Feathers-Sequelize中HasMany关联仅返回第一个关联数据的问题
兄弟我懂你这种卡关联配置的痛苦!我当初用Feathers-Sequelize的时候也踩过几乎一模一样的坑,给你一步步捋清楚怎么解决:
1. 先确认模型关联配置是否正确
首先要保证projects和issues模型的关联定义完全对应:
项目模型(projects.model.js)
module.exports = function (app) { const sequelizeClient = app.get('sequelizeClient'); const { DataTypes } = require('sequelize'); const projects = sequelizeClient.define('projects', { name: { type: DataTypes.STRING, allowNull: false } }, { hooks: { beforeCount(options) { options.raw = true; } } }); projects.associate = function (models) { // 配置HasMany关联,指定别名和外键 projects.hasMany(models.issues, { as: 'issues', foreignKey: 'projectId' }); }; return projects; };
问题模型(issues.model.js)
module.exports = function (app) { const sequelizeClient = app.get('sequelizeClient'); const { DataTypes } = require('sequelize'); const issues = sequelizeClient.define('issues', { title: { type: DataTypes.STRING, allowNull: false } }, { hooks: { beforeCount(options) { options.raw = true; } } }); issues.associate = function (models) { // 对应BelongsTo关联,外键要和projects模型里的配置一致 issues.belongsTo(models.projects, { as: 'project', foreignKey: 'projectId' }); }; return issues; };
2. 修改服务查询配置,启用嵌套关联返回
你之前拿到扁平字段的核心原因是默认使用了raw: true,这会让Sequelize把关联数据拆成扁平的issues.id格式,而不是嵌套数组。我们需要在查询时覆盖这个配置:
方式一:直接修改服务的get/find方法
比如在projects.service.js的get方法里调整:
const { errors } = require('@feathersjs/errors'); module.exports = class ProjectsService { constructor(options, app) { this.options = options; this.app = app; } async get(id, params) { const project = await this.Model.findByPk(id, { // 关联查询issues include: [{ model: this.app.services.issues.Model, as: 'issues' // 必须和模型里的别名一致 }], raw: false, // 禁用raw模式,保留Sequelize实例 nest: true // 强制关联数据嵌套成数组 }); if (!project) { throw new errors.NotFound('Project not found'); } // 转成JSON格式返回(也可以直接返回实例,Feathers会自动处理) return project.toJSON(); } };
方式二:用全局Hook统一处理所有查询
如果希望所有查询(find/get)都返回关联数据,可以在projects.hooks.js里添加before钩子:
module.exports = { before: { all: [], find: [ (context) => { context.params.sequelize = { include: [{ model: context.app.services.issues.Model, as: 'issues' }], raw: false, nest: true }; return context; } ], get: [ (context) => { context.params.sequelize = { include: [{ model: context.app.services.issues.Model, as: 'issues' }], raw: false, nest: true }; return context; } ] } };
3. 最后验证数据关联
确保issues表中的projectId字段正确关联到projects表的id,比如你测试用的两个issue的projectId都设置为1,这样查询project 1时就能拿到两个issue的数组了。
按照上面的步骤配置完,你就能得到期望的嵌套数组格式返回了!
内容的提问来源于stack exchange,提问作者MrSnoozles
相关产品推荐
相关产品推荐

