fix: parse nested associations in filterParser (#1941)
This commit is contained in:
parent
3ab4a3b68f
commit
ea6f7accc3
@ -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',
|
||||||
|
@ -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`);
|
||||||
|
Loading…
Reference in New Issue
Block a user