Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Too many nested levels! error #87

Open
roland-chernov opened this issue May 30, 2019 · 17 comments 路 Fixed by #146
Open

Too many nested levels! error #87

roland-chernov opened this issue May 30, 2019 · 17 comments 路 Fixed by #146

Comments

@roland-chernov
Copy link
Contributor

Hi everyone,

Could you help with the filtering on nested fields? It doesn't support nesting more than 2 levels deep, I wonder what is the reason for this limit 馃

if (nests.length > 2) {
this.throwBadRequestException(
'Too many nested levels! ' +
`Usage: '[join=<other-relation>&]join=[<other-relation>.]<relation>&filter=<relation>.<field>||op||val'`,
);
}

Could you clarify if there are any plans to make this limit customizable?

Thanks,
Roland

@michaelyali
Copy link
Member

Actually, we need to ask @Diluka about that. He's more efficient with this part of the lib because it was his feature.

@Diluka
Copy link
Contributor

Diluka commented May 31, 2019

@roland-chernov-akvelon
typeorm only allow alias.property form.
if you have nested properties like company.projects.tasks.name will be split into
company.projects alias projects and projects.tasks alias tasks and tasks.name for the full path company.projects.tasks.name

@roland-chernov
Copy link
Contributor Author

@Diluka Thanks for the quick response. So in other words, if I want to filter by company.projects.tasks.name I need to use a filter like: filter=tasks.name||eq||Some task?

Unfortunately, it fails for me with the Invalid relation name error here: https://github.com/nestjsx/crud/blob/master/src/typeorm/repository-service.class.ts#L394-#L396

I can try to implement an integration test if needed.

@Diluka
Copy link
Contributor

Diluka commented Jun 3, 2019

@roland-chernov-akvelon Do you remember to join? join=company.projects&join=projects.tasks&filter=tasks.name||eq||Some task

@SinPP
Copy link

SinPP commented Jun 3, 2019

Same error for me.

jobs?join=address&filter=address.id||eq||99&join=address.state&filter=state.id||eq||10

results in:

{ "statusCode": 400, "error": "Bad Request", "message": "Invalid relation name 'state'" }

@roland-chernov
Copy link
Contributor Author

Do you remember to join? join=company.projects&join=projects.tasks&filter=tasks.name||eq||Some task

@Diluka Sure, API returns all joined results but fails to filter.

@Diluka
Copy link
Contributor

Diluka commented Jun 4, 2019

private hasRelation(column: string): boolean {
return this.entityRelationsHash[column];
}

This is a bug. There shall check name instead of path.

@Diluka
Copy link
Contributor

Diluka commented Jun 4, 2019

I can't reproduce this issue on master branch. Can you make a PR with a test in test/typeorm/issue-87.spec.ts. @roland-chernov-akvelon

black-roland pushed a commit to roland-chernov/crud that referenced this issue Jun 4, 2019
@roland-chernov
Copy link
Contributor Author

@Diluka Please check master...roland-chernov-akvelon:issue-87 , I hope I set up it correctly 馃

To reproduce this issue:

  • I've added /tasks controller which allows fetching tasks.user.company entities;
  • And removed the direct relation between Task and Company.

TasksService.entityRelationsHash doesn't contain direct relation to Company and fails to filter entities by company fields but successfully returns related entities.

Please let me know if you have any questions.

@ignatvilesov
Copy link

We have dug this issue deep and figured out that we can use id to filter by nested entities.

Broken

join=task&join=task.owner&filter=task.owner.name||eq||Alex'

Working

join=task&join=task.owner&filter=task.owner||eq||1'

@SinPP
Copy link

SinPP commented Jun 12, 2019

@ignatvilesov

So what that means is that we cannot filter nested relationships by something other than id?

@Diluka
Copy link
Contributor

Diluka commented Jun 14, 2019

@roland-chernov-akvelon
I refactor the test into 4.x https://github.com/nestjsx/crud/tree/fix/issue-87
It passed all tests in local environment.

@zMotivat0r but one test failed in ci environment and ci reports ok. is this normal?

@michaelyali
Copy link
Member

@Diluka yeah, that's really strange. I'll try to see what happens here today

@ignatvilesov
Copy link

@SinPP It was true for v3.x.x but I haven't tested v4.x.x yet

@roland-chernov
Copy link
Contributor Author

@Diluka The error occurs when there is no direct relation between Task and Company. So filtering fails in the case when entities are related through another one.

Please see this commit: roland-chernov@a32bd0b

@njournaud
Copy link

njournaud commented Dec 19, 2019

Hi guys!

I have the same problem as rolan-chernov-akvelon.
Can you help me with it ?
In my case I have to filter project by code (string) :
user - oneToMany - company - oneToMany - projects
so if I read the doc I need to do like this ;
join=companies&join=companies.projects&filter=companies.projects.code||eq||hello
If I do only the join section it's work fine but when i'm adding the filter after it's fine too.
But if I do the joins with the filter I got "Invalid relation name companies.projects".
I'had test with company.projects but I got the same error with company.projects.

My entities :
User

  @PrimaryColumn('varchar', { length: 20, unique: true })
  @IsString()
  id!: string;

  @OneToMany(type => Company, comp=> comp.user, { cascade: false })
  companies!: Company[];

Company :

  @PrimaryColumn('varchar', { length: 20, unique: true })
  @IsString()
  code!: string;

  @Column({ nullable: false })
  @IsString()
  name!: string;

  @OneToMany(type => Project, project=> project.company, { cascade: false })
  projects!: Project[];

  @ManyToOne(type => User, user=> user.companies, { cascade: false, eager: false, nullable: false })
  @JoinColumn({ name: 'id_user' })
  user!: User;

Project:

  @PrimaryColumn('varchar', { nullable: false })
  code!: string;

  @ManyToOne(type => Company, comp=> comp.projects, { primary: true, nullable: false, cascade: false })
  @JoinColumn({ name: 'code_company', referencedColumnName: 'code' })
  company!: Company;

Thx you for your help.

@Diluka
Copy link
Contributor

Diluka commented Sep 16, 2020

there is still a bug, if nested property more 2 levels

this loop will add more than 2 levels' path

if (i !== fields.length - 1) {
parentPath = !parentPath
? propertyName
: /* istanbul ignore next */ `${parentPath}.${propertyName}`;
}

and here will pass it to query builder directly and raise an error

builder[relationType](allowedRelation.path, alias);

@Diluka Diluka reopened this Sep 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants