fix: populate is ignored for nested relationships (#11227)

### What?
As described in https://github.com/payloadcms/payload/issues/11209,
previously, the `populate` argument was ignored for nested
relationships.

### Why?
`populate` should work for nested relationships, no matter where they
are in the tree.

### How?
Preserves the `populate` argument in the payload data loader.

Fixes https://github.com/payloadcms/payload/issues/11209
This commit is contained in:
Sasha
2025-02-17 19:44:21 +02:00
committed by GitHub
parent 64d0217456
commit 938472bf1f
5 changed files with 118 additions and 20 deletions

View File

@@ -3,7 +3,7 @@ import type { BatchLoadFn } from 'dataloader'
import DataLoader from 'dataloader' import DataLoader from 'dataloader'
import type { PayloadRequest, SelectType } from '../types/index.js' import type { PayloadRequest, PopulateType, SelectType } from '../types/index.js'
import type { TypeWithID } from './config/types.js' import type { TypeWithID } from './config/types.js'
import { isValidID } from '../utilities/isValidID.js' import { isValidID } from '../utilities/isValidID.js'
@@ -57,6 +57,7 @@ const batchAndLoadDocs =
showHiddenFields, showHiddenFields,
draft, draft,
select, select,
populate,
] = JSON.parse(key) ] = JSON.parse(key)
const batchKeyArray = [ const batchKeyArray = [
@@ -70,6 +71,7 @@ const batchAndLoadDocs =
showHiddenFields, showHiddenFields,
draft, draft,
select, select,
populate,
] ]
const batchKey = JSON.stringify(batchKeyArray) const batchKey = JSON.stringify(batchKeyArray)
@@ -107,6 +109,7 @@ const batchAndLoadDocs =
showHiddenFields, showHiddenFields,
draft, draft,
select, select,
populate,
] = JSON.parse(batchKey) ] = JSON.parse(batchKey)
req.transactionID = transactionID req.transactionID = transactionID
@@ -121,6 +124,7 @@ const batchAndLoadDocs =
locale, locale,
overrideAccess: Boolean(overrideAccess), overrideAccess: Boolean(overrideAccess),
pagination: false, pagination: false,
populate,
req, req,
select, select,
showHiddenFields: Boolean(showHiddenFields), showHiddenFields: Boolean(showHiddenFields),
@@ -144,6 +148,7 @@ const batchAndLoadDocs =
fallbackLocale, fallbackLocale,
locale, locale,
overrideAccess, overrideAccess,
populate,
select, select,
showHiddenFields, showHiddenFields,
transactionID: req.transactionID, transactionID: req.transactionID,
@@ -173,6 +178,7 @@ type CreateCacheKeyArgs = {
fallbackLocale: string fallbackLocale: string
locale: string locale: string
overrideAccess: boolean overrideAccess: boolean
populate?: PopulateType
select?: SelectType select?: SelectType
showHiddenFields: boolean showHiddenFields: boolean
transactionID: number | Promise<number | string> | string transactionID: number | Promise<number | string> | string
@@ -186,6 +192,7 @@ export const createDataloaderCacheKey = ({
fallbackLocale, fallbackLocale,
locale, locale,
overrideAccess, overrideAccess,
populate,
select, select,
showHiddenFields, showHiddenFields,
transactionID, transactionID,
@@ -202,4 +209,5 @@ export const createDataloaderCacheKey = ({
showHiddenFields, showHiddenFields,
draft, draft,
select, select,
populate,
]) ])

View File

@@ -72,6 +72,7 @@ const populate = async ({
fallbackLocale, fallbackLocale,
locale, locale,
overrideAccess, overrideAccess,
populate: populateArg,
select: select:
populateArg?.[relatedCollection.config.slug] ?? populateArg?.[relatedCollection.config.slug] ??
relatedCollection.config.defaultPopulate, relatedCollection.config.defaultPopulate,

View File

@@ -21,6 +21,11 @@ export const Pages: CollectionConfig<'pages'> = {
}, },
access: { read: () => true }, access: { read: () => true },
fields: [ fields: [
{
name: 'relatedPage',
type: 'relationship',
relationTo: 'pages',
},
{ {
name: 'content', name: 'content',
type: 'blocks', type: 'blocks',

View File

@@ -2230,6 +2230,33 @@ describe('Select', () => {
expect(richTextLexicalRel.value).toMatchObject(expectedHomePageOverride) expect(richTextLexicalRel.value).toMatchObject(expectedHomePageOverride)
expect(richTextSlateRel.value).toMatchObject(expectedHomePageOverride) expect(richTextSlateRel.value).toMatchObject(expectedHomePageOverride)
}) })
it('should apply populate on depth 2', async () => {
const page_1 = await payload.create({
collection: 'pages',
data: { relatedPage: null, blocks: [{ blockType: 'some' }], slug: 'page-1' },
})
const page_2 = await payload.create({
collection: 'pages',
data: { relatedPage: page_1.id, slug: 'page-2' },
})
const page_3 = await payload.create({
collection: 'pages',
data: { relatedPage: page_2.id, slug: 'page-3' },
})
const result = await payload.findByID({
collection: 'pages',
id: page_3.id,
depth: 3,
populate: { pages: { slug: true, relatedPage: true } },
})
expect(result.relatedPage.id).toBe(page_2.id)
expect(result.relatedPage.relatedPage as Page).toStrictEqual({
id: page_1.id,
slug: page_1.slug,
relatedPage: null,
})
})
}) })
}) })

View File

@@ -6,10 +6,65 @@
* and re-run `payload generate:types` to regenerate this file. * and re-run `payload generate:types` to regenerate this file.
*/ */
/**
* Supported timezones in IANA format.
*
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "supportedTimezones".
*/
export type SupportedTimezones =
| 'Pacific/Midway'
| 'Pacific/Niue'
| 'Pacific/Honolulu'
| 'Pacific/Rarotonga'
| 'America/Anchorage'
| 'Pacific/Gambier'
| 'America/Los_Angeles'
| 'America/Tijuana'
| 'America/Denver'
| 'America/Phoenix'
| 'America/Chicago'
| 'America/Guatemala'
| 'America/New_York'
| 'America/Bogota'
| 'America/Caracas'
| 'America/Santiago'
| 'America/Buenos_Aires'
| 'America/Sao_Paulo'
| 'Atlantic/South_Georgia'
| 'Atlantic/Azores'
| 'Atlantic/Cape_Verde'
| 'Europe/London'
| 'Europe/Berlin'
| 'Africa/Lagos'
| 'Europe/Athens'
| 'Africa/Cairo'
| 'Europe/Moscow'
| 'Asia/Riyadh'
| 'Asia/Dubai'
| 'Asia/Baku'
| 'Asia/Karachi'
| 'Asia/Tashkent'
| 'Asia/Calcutta'
| 'Asia/Dhaka'
| 'Asia/Almaty'
| 'Asia/Jakarta'
| 'Asia/Bangkok'
| 'Asia/Shanghai'
| 'Asia/Singapore'
| 'Asia/Tokyo'
| 'Asia/Seoul'
| 'Australia/Sydney'
| 'Pacific/Guam'
| 'Pacific/Noumea'
| 'Pacific/Auckland'
| 'Pacific/Fiji';
export interface Config { export interface Config {
auth: { auth: {
users: UserAuthOperations; users: UserAuthOperations;
}; };
blocks: {};
collections: { collections: {
posts: Post; posts: Post;
'localized-posts': LocalizedPost; 'localized-posts': LocalizedPost;
@@ -122,7 +177,7 @@ export interface Post {
unnamedTabNumber?: number | null; unnamedTabNumber?: number | null;
hasOne?: (string | null) | Rel; hasOne?: (string | null) | Rel;
hasMany?: (string | Rel)[] | null; hasMany?: (string | Rel)[] | null;
hasManyUpload?: (string | Rel)[] | null; hasManyUpload?: (string | Upload)[] | null;
hasOnePoly?: { hasOnePoly?: {
relationTo: 'rels'; relationTo: 'rels';
value: string | Rel; value: string | Rel;
@@ -145,6 +200,24 @@ export interface Rel {
updatedAt: string; updatedAt: string;
createdAt: string; createdAt: string;
} }
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "upload".
*/
export interface Upload {
id: string;
updatedAt: string;
createdAt: string;
url?: string | null;
thumbnailURL?: string | null;
filename?: string | null;
mimeType?: string | null;
filesize?: number | null;
width?: number | null;
height?: number | null;
focalX?: number | null;
focalY?: number | null;
}
/** /**
* This interface was referenced by `Config`'s JSON-Schema * This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "localized-posts". * via the `definition` "localized-posts".
@@ -290,6 +363,7 @@ export interface DeepPost {
*/ */
export interface Page { export interface Page {
id: string; id: string;
relatedPage?: (string | null) | Page;
content?: content?:
| { | {
title: string; title: string;
@@ -369,24 +443,6 @@ export interface Point {
updatedAt: string; updatedAt: string;
createdAt: string; createdAt: string;
} }
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "upload".
*/
export interface Upload {
id: string;
updatedAt: string;
createdAt: string;
url?: string | null;
thumbnailURL?: string | null;
filename?: string | null;
mimeType?: string | null;
filesize?: number | null;
width?: number | null;
height?: number | null;
focalX?: number | null;
focalY?: number | null;
}
/** /**
* This interface was referenced by `Config`'s JSON-Schema * This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "users". * via the `definition` "users".
@@ -706,6 +762,7 @@ export interface DeepPostsSelect<T extends boolean = true> {
* via the `definition` "pages_select". * via the `definition` "pages_select".
*/ */
export interface PagesSelect<T extends boolean = true> { export interface PagesSelect<T extends boolean = true> {
relatedPage?: T;
content?: content?:
| T | T
| { | {