From 74ed6230b35c41e264854fafcb4c60667ff7ac99 Mon Sep 17 00:00:00 2001 From: Romain Gilliotte Date: Wed, 12 May 2021 14:45:33 +0200 Subject: [PATCH] fix: regression when fetching has-many and not selecting any fields on a hasone/belongsto relation (#720) --- src/services/has-many-getter.js | 4 ++-- src/services/line-stat-getter.js | 19 ++++++++++++------- src/services/pie-stat-getter.js | 18 +++++++++++------- test/databases.test.js | 28 ++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/src/services/has-many-getter.js b/src/services/has-many-getter.js index 967abbf6..346f57a9 100644 --- a/src/services/has-many-getter.js +++ b/src/services/has-many-getter.js @@ -1,3 +1,4 @@ +import { pick } from 'lodash'; import Operators from '../utils/operators'; import QueryUtils from '../utils/query'; import PrimaryKeysManager from './primary-keys-manager'; @@ -35,8 +36,7 @@ class HasManyGetter extends ResourcesGetter { as: associationName, scope: false, required: !!buildOptions.forCount, // Why? - where: options.where, - include: options.include, + ...pick(options, ['where', 'include']), }], }); diff --git a/src/services/line-stat-getter.js b/src/services/line-stat-getter.js index 741f9642..e3821e23 100644 --- a/src/services/line-stat-getter.js +++ b/src/services/line-stat-getter.js @@ -201,17 +201,22 @@ ${groupByDateFieldFormated}), 'yyyy-MM-dd 00:00:00')`); const queryOptions = new QueryOptions(model, { includeRelations: true }); await queryOptions.filterByConditionTree(filters, timezone); - const { include, where } = queryOptions.sequelizeOptions; - const records = await model.unscoped().findAll({ - include: include - ? include.map((includeProperties) => ({ ...includeProperties, attributes: [] })) - : undefined, - where, + const sequelizeOptions = { + ...queryOptions.sequelizeOptions, attributes: [getGroupByDateInterval(), getAggregate()], group: getGroupBy(), order: getOrder(), raw: true, - }); + }; + + // do not load related properties + if (sequelizeOptions.include) { + sequelizeOptions.include = sequelizeOptions.include.map( + (includeProperties) => ({ ...includeProperties, attributes: [] }), + ); + } + + const records = await model.unscoped().findAll(sequelizeOptions); return { value: fillEmptyDateInterval( diff --git a/src/services/pie-stat-getter.js b/src/services/pie-stat-getter.js index 4883f883..5a4dc7f2 100644 --- a/src/services/pie-stat-getter.js +++ b/src/services/pie-stat-getter.js @@ -85,12 +85,8 @@ function PieStatGetter(model, params, options) { const queryOptions = new QueryOptions(model, { includeRelations: true }); await queryOptions.filterByConditionTree(filters, timezone); - const { include, where } = queryOptions.sequelizeOptions; - const records = await model.unscoped().findAll({ - include: include - ? include.map((includeProperties) => ({ ...includeProperties, attributes: [] })) - : undefined, - where, + const sequelizeOptions = { + ...queryOptions.sequelizeOptions, attributes: [ [options.Sequelize.col(groupByField), ALIAS_GROUP_BY], [ @@ -101,7 +97,15 @@ function PieStatGetter(model, params, options) { group: getGroupBy(), order: [[options.Sequelize.literal(ALIAS_AGGREGATE), 'DESC']], raw: true, - }); + }; + + if (sequelizeOptions.include) { + sequelizeOptions.include = sequelizeOptions.include.map( + (includeProperties) => ({ ...includeProperties, attributes: [] }), + ); + } + + const records = await model.unscoped().findAll(sequelizeOptions); return { value: formatResults(records) }; }; diff --git a/test/databases.test.js b/test/databases.test.js index 2444843e..a4129388 100644 --- a/test/databases.test.js +++ b/test/databases.test.js @@ -2990,6 +2990,34 @@ const HasManyDissociator = require('../src/services/has-many-dissociator'); }); }); + describe('request on the has-many getter without relations', () => { + it('should generate a valid SQL query', async () => { + expect.assertions(1); + const { models, sequelizeOptions } = initializeSequelize(); + const params = { + recordId: 100, + associationName: 'addresses', + fields: { + address: 'line,zipCode,city,country', + }, + page: { number: '1', size: '20' }, + timezone: 'Europe/Paris', + }; + try { + await new HasManyGetter( + models.user, + models.address, + sequelizeOptions, + params, + ) + .perform(); + expect(true).toBeTrue(); + } finally { + connectionManager.closeConnection(); + } + }); + }); + describe('request on the has-many-getter with a sort on an attribute', () => { it('should generate a valid SQL query', async () => { expect.assertions(1);