nestjsx / crud

NestJs CRUD for RESTful APIs
https://github.com/nestjsx/crud/wiki
MIT License
4.04k stars 534 forks source link

`Too many nested levels!` error #87

Open roland-chernov opened 5 years ago

roland-chernov commented 5 years ago

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 :thinking: https://github.com/nestjsx/crud/blob/a6a5f3d54351bfb93231aeeac3a27e1409b1ecb0/src/typeorm/repository-service.class.ts#L386-L391

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

Thanks, Roland

michaelyali commented 5 years ago

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

Diluka commented 5 years ago

@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 commented 5 years ago

@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 commented 5 years ago

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

SinPP commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

https://github.com/nestjsx/crud/blob/e71906d9560d2f5be4020787cf342ddb83df8c1e/src/typeorm/repository-service.class.ts#L379-L381

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

Diluka commented 5 years ago

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

roland-chernov commented 5 years ago

@Diluka Please check https://github.com/nestjsx/crud/compare/master...roland-chernov-akvelon:issue-87 , I hope I set up it correctly :thinking:

To reproduce this issue:

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 commented 5 years ago

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 commented 5 years ago

@ignatvilesov

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

Diluka commented 5 years ago

@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 commented 5 years ago

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

ignatvilesov commented 5 years ago

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

roland-chernov commented 5 years ago

@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: https://github.com/roland-chernov-akvelon/crud/commit/a32bd0bf491728aa1a27d366a4e1fa054515df24

njournaud commented 4 years ago

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 commented 4 years ago

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

this loop will add more than 2 levels' path https://github.com/nestjsx/crud/blob/77bb83adc0631747a5dcb07d101f19f5dc295c14/packages/crud-typeorm/src/typeorm-crud.service.ts#L490-L494

and here will pass it to query builder directly and raise an error https://github.com/nestjsx/crud/blob/77bb83adc0631747a5dcb07d101f19f5dc295c14/packages/crud-typeorm/src/typeorm-crud.service.ts#L573