diff --git a/packages/core/database/lib/query/helpers/populate/apply.js b/packages/core/database/lib/query/helpers/populate/apply.js index 2ae346d135..130f2aa093 100644 --- a/packages/core/database/lib/query/helpers/populate/apply.js +++ b/packages/core/database/lib/query/helpers/populate/apply.js @@ -470,6 +470,8 @@ const morphToMany = async (input, ctx) => { }, {}); const map = {}; + const { on, ...typePopulate } = populateValue; + for (const type of Object.keys(idsByType)) { const ids = idsByType[type]; @@ -480,10 +482,14 @@ const morphToMany = async (input, ctx) => { continue; } + if (on && on[type]) { + Object.assign(typePopulate, on[type]); + } + const qb = db.entityManager.createQueryBuilder(type); const rows = await qb - .init(populateValue) + .init(typePopulate) .addSelect(`${qb.alias}.${idColumn.referencedColumn}`) .where({ [idColumn.referencedColumn]: ids }) .execute({ mapResults: false }); @@ -579,7 +585,16 @@ const morphToOne = async (input, ctx) => { // TODO: Omit limit & offset to avoid needing a query per result to avoid making too many queries const pickPopulateParams = (populate) => { - const fieldsToPick = ['select', 'count', 'where', 'populate', 'orderBy', 'filters', 'ordering']; + const fieldsToPick = [ + 'select', + 'count', + 'where', + 'populate', + 'orderBy', + 'filters', + 'ordering', + 'on', + ]; if (populate.count !== true) { fieldsToPick.push('limit', 'offset'); diff --git a/packages/core/utils/lib/convert-query-params.js b/packages/core/utils/lib/convert-query-params.js index 38d1af385b..4c11510375 100644 --- a/packages/core/utils/lib/convert-query-params.js +++ b/packages/core/utils/lib/convert-query-params.js @@ -6,17 +6,17 @@ * Converts the standard Strapi REST query params to a more usable format for querying * You can read more here: https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/rest-api.html#filters */ + const { + isNil, + toNumber, + isInteger, has, isEmpty, isObject, isPlainObject, cloneDeep, get, - mergeAll, - isNil, - toNumber, - isInteger, } = require('lodash/fp'); const _ = require('lodash'); const parseType = require('./parse-type'); @@ -185,22 +185,19 @@ const convertPopulateObject = (populate, schema) => { return acc; } - // FIXME: This is a temporary solution for dynamic zones that should be - // fixed when we'll implement a more accurate way to query them - if (attribute.type === 'dynamiczone') { - const populates = attribute.components - .map((uid) => strapi.getModel(uid)) - .map((schema) => convertNestedPopulate(subPopulate, schema)) - .map((populate) => (populate === true ? {} : populate)) // cast boolean to empty object to avoid merging issues - .filter((populate) => populate !== false); - - if (isEmpty(populates)) { - return acc; - } - + if (subPopulate && subPopulate.on) { return { ...acc, - [key]: mergeAll(populates), + [key]: { + ...subPopulate, + on: Object.entries(subPopulate.on).reduce( + (newTypeSubPopulate, [type, typeSubPopulate]) => ({ + ...newTypeSubPopulate, + [type]: convertNestedPopulate(typeSubPopulate, strapi.getModel(type)), + }), + {} + ), + }, }; }