fix: parse nested associations in filterParser (#1941)

This commit is contained in:
ChengLei Shao 2023-05-26 14:48:20 +08:00 committed by GitHub
parent 3ab4a3b68f
commit ea6f7accc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 9 deletions

View File

@ -14,6 +14,60 @@ describe('filter', () => {
await db.close(); await db.close();
}); });
it('should filter by belongs to many association', async () => {
const A = db.collection({
name: 'a',
fields: [
{ type: 'string', name: 'name' },
{ type: 'hasMany', name: 'b', target: 'b' },
],
});
const B = db.collection({
name: 'b',
fields: [
{ type: 'string', name: 'name' },
{ type: 'belongsTo', name: 'c', target: 'c' },
{ type: 'belongsTo', name: 'd', target: 'd' },
],
});
const C = db.collection({
name: 'c',
fields: [{ type: 'string', name: 'name' }],
});
const D = db.collection({
name: 'd',
fields: [{ type: 'string', name: 'name' }],
});
await db.sync();
const findArgs = {
filter: {
$and: [{ b: { c: { name: { $eq: 'c1' } } } }, { b: { d: { name: { $eq: 'd1' } } } }],
},
};
const findOptions = A.repository.buildQueryOptions(findArgs);
const include = findOptions.include;
const associationB = include.find((i) => i.association === 'b');
expect(associationB).toBeDefined();
expect(associationB.include).toHaveLength(2);
let err;
try {
await A.repository.find({ ...findArgs });
} catch (e) {
err = e;
}
expect(err).toBeUndefined();
});
it('should filter by hasMany association field', async () => { it('should filter by hasMany association field', async () => {
const DeptCollection = db.collection({ const DeptCollection = db.collection({
name: 'depts', name: 'depts',

View File

@ -164,11 +164,15 @@ export default class FilterParser {
debug('associationKeys %o', associationKeys); debug('associationKeys %o', associationKeys);
// set sequelize include option const existInclude = _.get(include, firstKey);
_.set(include, firstKey, {
association: firstKey, if (!existInclude) {
attributes: [], // out put empty fields by default // set sequelize include option
}); _.set(include, firstKey, {
association: firstKey,
attributes: [], // out put empty fields by default
});
}
// association target model // association target model
let target = associations[firstKey].target; let target = associations[firstKey].target;
@ -192,10 +196,14 @@ export default class FilterParser {
assoc.push(associationKey); assoc.push(associationKey);
}); });
_.set(include, assoc, { const existInclude = _.get(include, assoc);
association: attr, if (!existInclude) {
attributes: [], _.set(include, assoc, {
}); association: attr,
attributes: [],
});
}
target = target.associations[attr].target; target = target.associations[attr].target;
} else { } else {
throw new Error(`${attr} neither ${firstKey}'s association nor ${firstKey}'s attribute`); throw new Error(`${attr} neither ${firstKey}'s association nor ${firstKey}'s attribute`);