mirror of
https://github.com/strapi/strapi.git
synced 2025-12-26 06:35:47 +00:00
refacto findWithRelationCounts
This commit is contained in:
parent
df3a40c84b
commit
885dc5a138
@ -1,6 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const pmap = require('p-map');
|
||||
const { prop } = require('lodash/fp');
|
||||
const { MANY_RELATIONS } = require('strapi-utils').relations.constants;
|
||||
|
||||
const { createQueryWithLifecycles, withLifecycles } = require('./helpers');
|
||||
const { createFindPageQuery, createSearchPageQuery } = require('./paginated-queries');
|
||||
@ -19,6 +21,42 @@ module.exports = function createQuery(opts) {
|
||||
connectorQuery,
|
||||
});
|
||||
|
||||
const findOrSearchWithRelationCounts = method =>
|
||||
async function(params, populate) {
|
||||
const xManyAssocs = [];
|
||||
const xToOnePopulate = [];
|
||||
model.associations
|
||||
.filter(assoc => !populate || populate.includes(assoc.alias))
|
||||
.forEach(assoc => {
|
||||
if (MANY_RELATIONS.includes(assoc.nature)) {
|
||||
xManyAssocs.push(assoc);
|
||||
} else {
|
||||
xToOnePopulate.push(assoc.alias);
|
||||
}
|
||||
});
|
||||
|
||||
const { results, pagination } = await this[method](params, model, xToOnePopulate);
|
||||
const resultsIds = results.map(prop('id'));
|
||||
|
||||
const counters = await Promise.all(
|
||||
xManyAssocs.map(async assoc => ({
|
||||
field: assoc.alias,
|
||||
counts: await this.fetchRelationCounters(assoc.alias, resultsIds),
|
||||
}))
|
||||
);
|
||||
|
||||
results.forEach(entity => {
|
||||
counters.forEach(counter => {
|
||||
entity[counter.field] = { count: counter.counts[entity.id] || 0 };
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
results,
|
||||
pagination,
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
get model() {
|
||||
return model;
|
||||
@ -79,5 +117,11 @@ module.exports = function createQuery(opts) {
|
||||
model,
|
||||
fn: createSearchPageQuery(connectorQuery),
|
||||
}),
|
||||
searchWithRelationCounts(...args) {
|
||||
return findOrSearchWithRelationCounts('searchPage').bind(this)(...args);
|
||||
},
|
||||
findWithRelationCounts(...args) {
|
||||
return findOrSearchWithRelationCounts('findPage').bind(this)(...args);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const { has, pipe, prop, pick } = require('lodash/fp');
|
||||
const { MANY_RELATIONS } = require('strapi-utils').relations.constants;
|
||||
|
||||
const {
|
||||
getService,
|
||||
@ -8,7 +9,6 @@ const {
|
||||
setCreatorFields,
|
||||
pickWritableAttributes,
|
||||
} = require('../utils');
|
||||
const { MANY_RELATIONS } = require('../services/constants');
|
||||
const { validateBulkDeleteInput, validatePagination } = require('./validation');
|
||||
|
||||
module.exports = {
|
||||
@ -24,36 +24,11 @@ module.exports = {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const method = has('_q', query) ? 'searchPage' : 'findPage';
|
||||
const method = has('_q', query) ? 'searchWithRelationCounts' : 'findWithRelationCounts';
|
||||
|
||||
const permissionQuery = permissionChecker.buildPermissionQuery(query);
|
||||
|
||||
const modelDef = strapi.getModel(model);
|
||||
const xManyAssocs = [];
|
||||
const populate = [];
|
||||
modelDef.associations.forEach(assoc => {
|
||||
if (MANY_RELATIONS.includes(assoc.nature)) {
|
||||
xManyAssocs.push(assoc);
|
||||
} else {
|
||||
populate.push(assoc.alias);
|
||||
}
|
||||
});
|
||||
|
||||
const { results, pagination } = await entityManager[method](permissionQuery, model, populate);
|
||||
const resultsIds = results.map(prop('id'));
|
||||
|
||||
const counters = await Promise.all(
|
||||
xManyAssocs.map(async assoc => ({
|
||||
field: assoc.alias,
|
||||
counts: await strapi.query(model).fetchRelationCounters(assoc.alias, resultsIds),
|
||||
}))
|
||||
);
|
||||
|
||||
results.forEach(entity => {
|
||||
counters.forEach(counter => {
|
||||
entity[counter.field] = { count: counter.counts[entity.id] || 0 };
|
||||
});
|
||||
});
|
||||
const { results, pagination } = await entityManager[method](permissionQuery, model);
|
||||
|
||||
ctx.body = {
|
||||
results: results.map(entity => permissionChecker.sanitizeOutput(entity)),
|
||||
|
||||
@ -52,6 +52,10 @@ module.exports = {
|
||||
return strapi.entityService.findPage({ params, populate }, { model });
|
||||
},
|
||||
|
||||
findWithRelationCounts(params, model, populate) {
|
||||
return strapi.entityService.findWithRelationCounts({ params, populate }, { model });
|
||||
},
|
||||
|
||||
search(params, model, populate) {
|
||||
return strapi.entityService.search({ params, populate }, { model });
|
||||
},
|
||||
@ -60,6 +64,10 @@ module.exports = {
|
||||
return strapi.entityService.searchPage({ params, populate }, { model });
|
||||
},
|
||||
|
||||
searchWithRelationCounts(params, model, populate) {
|
||||
return strapi.entityService.searchWithRelationCounts({ params, populate }, { model });
|
||||
},
|
||||
|
||||
count(params, model) {
|
||||
return strapi.entityService.count({ params }, { model });
|
||||
},
|
||||
|
||||
@ -32,6 +32,7 @@ const { generateTimestampCode } = require('./code-generator');
|
||||
const contentTypes = require('./content-types');
|
||||
const webhook = require('./webhook');
|
||||
const env = require('./env-helper');
|
||||
const relations = require('./relations');
|
||||
|
||||
module.exports = {
|
||||
yup,
|
||||
@ -63,4 +64,5 @@ module.exports = {
|
||||
contentTypes,
|
||||
webhook,
|
||||
env,
|
||||
relations,
|
||||
};
|
||||
|
||||
@ -3,5 +3,7 @@
|
||||
const MANY_RELATIONS = ['oneToMany', 'manyToMany', 'manyWay'];
|
||||
|
||||
module.exports = {
|
||||
MANY_RELATIONS,
|
||||
constants: {
|
||||
MANY_RELATIONS,
|
||||
},
|
||||
};
|
||||
@ -37,6 +37,10 @@ module.exports = ({ db, eventHub, entityValidator }) => ({
|
||||
return db.query(model).findPage(params, populate);
|
||||
},
|
||||
|
||||
findWithRelationCounts({ params, populate }, { model }) {
|
||||
return db.query(model).findWithRelationCounts(params, populate);
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to fetch record
|
||||
*
|
||||
@ -152,6 +156,10 @@ module.exports = ({ db, eventHub, entityValidator }) => ({
|
||||
return db.query(model).search(params, populate);
|
||||
},
|
||||
|
||||
searchWithRelationCounts({ params, populate }, { model }) {
|
||||
return db.query(model).searchWithRelationCounts(params, populate);
|
||||
},
|
||||
|
||||
searchPage({ params, populate }, { model }) {
|
||||
return db.query(model).searchPage(params, populate);
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user