fix: querying relationships by id path with REST (#9013)

### What?
Fixes the issue with querying by `id` from REST / `overrideAccess:
false`.
For example, this didn't work:

`/api/loans?where[book.bibliography.id][equals]=67224d74257b3f2acddc75f4`
```
QueryError: The following path cannot be queried: id
```

### Why?
We support this syntax within the Local API.

### How?
Now, for simplicity we sanitize everything like
`relation.otherRelation.id` to `relation.otherRelation`

Fixes https://github.com/payloadcms/payload/issues/9008
This commit is contained in:
Sasha
2024-11-04 17:57:41 +02:00
committed by GitHub
parent f10a160462
commit 5b97ac1a67
2 changed files with 43 additions and 0 deletions

View File

@@ -73,6 +73,19 @@ export async function validateSearchParam({
})
}
const promises = []
// Sanitize relation.otherRelation.id to relation.otherRelation
if (paths.at(-1)?.path === 'id') {
const previousField = paths.at(-2)?.field
if (
previousField &&
(previousField.type === 'relationship' || previousField.type === 'upload') &&
typeof previousField.relationTo === 'string'
) {
paths.pop()
}
}
promises.push(
...paths.map(async ({ collectionSlug, field, invalid, path }, i) => {
if (invalid) {
@@ -115,6 +128,7 @@ export async function validateSearchParam({
) {
fieldPath = fieldPath.replace('.value', '')
}
const entityType: 'collections' | 'globals' = globalConfig ? 'globals' : 'collections'
const entitySlug = collectionSlug || globalConfig.slug
const segments = fieldPath.split('.')

View File

@@ -875,6 +875,35 @@ describe('Relationships', () => {
expect(query.docs[0].id).toStrictEqual(firstLevelID)
})
it('should allow querying on id two levels deep', async () => {
const query = await payload.find({
collection: 'chained',
where: {
'relation.relation.id': {
equals: thirdLevelID,
},
},
})
expect(query.docs).toHaveLength(1)
expect(query.docs[0].id).toStrictEqual(firstLevelID)
const queryREST = await restClient
.GET(`/chained`, {
query: {
where: {
'relation.relation.id': {
equals: thirdLevelID,
},
},
},
})
.then((res) => res.json())
expect(queryREST.docs).toHaveLength(1)
expect(queryREST.docs[0].id).toStrictEqual(firstLevelID)
})
it('should allow querying within array nesting', async () => {
const page = await payload.create({
collection: 'pages',