fix(database): belongs to association only in eager loading tree (#3259)

* chore: test

* chore: test

* fix: belongs to association only in eager loading tree
This commit is contained in:
ChengLei Shao 2023-12-25 19:44:27 +08:00 committed by GitHub
parent f17e10caa4
commit bb07625af5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 115 additions and 6 deletions

View File

@ -14,6 +14,101 @@ describe('find with associations', () => {
await db.close();
});
// 关系数据分页测试
it('should filter with associations by pagination', async () => {
const Org = db.collection({
name: 'organizations',
fields: [
{ name: 'name', type: 'string' },
{
name: 'owner',
type: 'belongsTo',
target: 'users',
},
],
});
const User = db.collection({
name: 'users',
fields: [
{ name: 'name', type: 'string' },
{
name: 'qualifications',
type: 'belongsToMany',
target: 'qualifications',
},
],
});
const Qualification = db.collection({
name: 'qualifications',
fields: [
{ name: 'name', type: 'string' },
{
name: 'user',
type: 'belongsToMany',
target: 'users',
},
],
});
await db.sync();
await User.repository.create({
values: [
{
name: 'u1',
qualifications: [
{
name: 'q1',
},
{
name: 'q2',
},
],
},
{
name: 'u2',
qualifications: [
{
name: 'q1',
},
{
name: 'q2',
},
],
},
],
});
const u1 = await User.repository.findOne({ filter: { name: 'u1' } });
const u2 = await User.repository.findOne({ filter: { name: 'u2' } });
await Org.repository.create({
values: [
{
name: 'o1',
owner: u1.get('id'),
},
{
name: 'o2',
owner: u2.get('id'),
},
],
});
const orgs = await Org.repository.findAndCount({
limit: 2,
filter: {
$or: [{ 'owner.qualifications.name.$includes': 'q1' }, { 'owner.qualifications.name.$includes': 'q2' }],
},
});
const [results, count] = orgs;
expect(count).toEqual(2);
expect(results.length).toEqual(2);
});
it('should filter has many with limit', async () => {
const User = db.collection({
name: 'users',

View File

@ -4,6 +4,7 @@ import Database from '../database';
import { appendChildCollectionNameAfterRepositoryFind } from '../listeners/append-child-collection-name-after-repository-find';
import { OptionsParser } from '../options-parser';
import { AdjacencyListRepository } from '../repositories/tree-repository/adjacency-list-repository';
import association from '../operators/association';
interface EagerLoadingNode {
model: ModelStatic<any>;
@ -174,13 +175,26 @@ export class EagerLoadingTree {
);
});
const belongsToAssociationsOnly = includeForFilter.every((include) => {
const association = node.model.associations[include.association];
if (!association) {
return false;
const isBelongsToAssociationOnly = (includes, model) => {
for (const include of includes) {
const association = model.associations[include.association];
if (!association) {
return false;
}
if (association.associationType != 'BelongsTo') {
return false;
}
if (!isBelongsToAssociationOnly(include.include || [], association.target)) {
return false;
}
}
return association.associationType == 'BelongsTo';
});
return true;
};
const belongsToAssociationsOnly = isBelongsToAssociationOnly(includeForFilter, node.model);
if (belongsToAssociationsOnly) {
instances = await node.model.findAll({