From 5b97ac1a67967ec1e389537e55c280ffcd14702f Mon Sep 17 00:00:00 2001 From: Sasha <64744993+r1tsuu@users.noreply.github.com> Date: Mon, 4 Nov 2024 17:57:41 +0200 Subject: [PATCH] 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 --- .../queryValidation/validateSearchParams.ts | 14 +++++++++ test/relationships/int.spec.ts | 29 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/packages/payload/src/database/queryValidation/validateSearchParams.ts b/packages/payload/src/database/queryValidation/validateSearchParams.ts index 8a781a84c8..5df42fea5f 100644 --- a/packages/payload/src/database/queryValidation/validateSearchParams.ts +++ b/packages/payload/src/database/queryValidation/validateSearchParams.ts @@ -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('.') diff --git a/test/relationships/int.spec.ts b/test/relationships/int.spec.ts index 7b889ca190..5cba6536c8 100644 --- a/test/relationships/int.spec.ts +++ b/test/relationships/int.spec.ts @@ -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',