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();
|
||||
});
|
||||
|
||||
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 () => {
|
||||
const DeptCollection = db.collection({
|
||||
name: 'depts',
|
||||
|
@ -164,11 +164,15 @@ export default class FilterParser {
|
||||
|
||||
debug('associationKeys %o', associationKeys);
|
||||
|
||||
// set sequelize include option
|
||||
_.set(include, firstKey, {
|
||||
association: firstKey,
|
||||
attributes: [], // out put empty fields by default
|
||||
});
|
||||
const existInclude = _.get(include, firstKey);
|
||||
|
||||
if (!existInclude) {
|
||||
// set sequelize include option
|
||||
_.set(include, firstKey, {
|
||||
association: firstKey,
|
||||
attributes: [], // out put empty fields by default
|
||||
});
|
||||
}
|
||||
|
||||
// association target model
|
||||
let target = associations[firstKey].target;
|
||||
@ -192,10 +196,14 @@ export default class FilterParser {
|
||||
assoc.push(associationKey);
|
||||
});
|
||||
|
||||
_.set(include, assoc, {
|
||||
association: attr,
|
||||
attributes: [],
|
||||
});
|
||||
const existInclude = _.get(include, assoc);
|
||||
if (!existInclude) {
|
||||
_.set(include, assoc, {
|
||||
association: attr,
|
||||
attributes: [],
|
||||
});
|
||||
}
|
||||
|
||||
target = target.associations[attr].target;
|
||||
} else {
|
||||
throw new Error(`${attr} neither ${firstKey}'s association nor ${firstKey}'s attribute`);
|
||||
|
Loading…
Reference in New Issue
Block a user