Fix mongoose autopopulate recursively looping to infinity when cycles appear (#9367)

This commit is contained in:
Alexandre BODIN 2021-02-11 15:52:59 +01:00 committed by GitHub
parent 6b6a4f5c6b
commit a53d2dbaca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -311,7 +311,9 @@ module.exports = async ({ models, target }, ctx) => {
const createOnFetchPopulateFn = ({ morphAssociations, componentAttributes, definition }) => { const createOnFetchPopulateFn = ({ morphAssociations, componentAttributes, definition }) => {
return function() { return function() {
const populatedPaths = this.getPopulatedPaths(); const populatedPaths = this.getPopulatedPaths();
const { publicationState } = this.getOptions(); const { publicationState, _depth = 0 } = this.getOptions();
if (_depth > 2) return;
const getMatchQuery = assoc => { const getMatchQuery = assoc => {
const assocModel = strapi.db.getModelByAssoc(assoc); const assocModel = strapi.db.getModelByAssoc(assoc);
@ -334,7 +336,10 @@ const createOnFetchPopulateFn = ({ morphAssociations, componentAttributes, defin
this.populate({ path: alias, match: matchQuery, options: { publicationState } }); this.populate({ path: alias, match: matchQuery, options: { publicationState } });
} else if (populatedPaths.includes(alias)) { } else if (populatedPaths.includes(alias)) {
_.set(this._mongooseOptions.populate, [alias, 'path'], `${alias}.ref`); _.set(this._mongooseOptions.populate, [alias, 'path'], `${alias}.ref`);
_.set(this._mongooseOptions.populate, [alias, 'options'], { publicationState }); _.set(this._mongooseOptions.populate, [alias, 'options'], {
publicationState,
_depth: _depth + 1,
});
if (matchQuery !== undefined) { if (matchQuery !== undefined) {
_.set(this._mongooseOptions.populate, [alias, 'match'], matchQuery); _.set(this._mongooseOptions.populate, [alias, 'match'], matchQuery);
@ -350,13 +355,13 @@ const createOnFetchPopulateFn = ({ morphAssociations, componentAttributes, defin
this.populate({ this.populate({
path: ast.alias, path: ast.alias,
match: getMatchQuery(ast), match: getMatchQuery(ast),
options: { publicationState }, options: { publicationState, _depth: _depth + 1 },
}); });
}); });
} }
componentAttributes.forEach(key => { componentAttributes.forEach(key => {
this.populate({ path: `${key}.ref`, options: { publicationState } }); this.populate({ path: `${key}.ref`, options: { publicationState, _depth: _depth + 1 } });
}); });
}; };
}; };