Skip to content

Commit 1b2b6a1

Browse files
authored
fix: respect draft: true when querying docs for the join field (#11763)
Previously, if you were querying a collection that has a join field with `draft: true`, and the join field's collection also has `versions.drafts: true` our db adapter would still query the original SQL table / mongodb collection instead of the versions one which isn't quite right since we respect `draft: true` when populating relationships
1 parent 5f6bb92 commit 1b2b6a1

File tree

17 files changed

+165
-29
lines changed

17 files changed

+165
-29
lines changed

packages/db-mongodb/src/find.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const find: Find = async function find(
1818
this: MongooseAdapter,
1919
{
2020
collection: collectionSlug,
21+
draftsEnabled,
2122
joins = {},
2223
limit = 0,
2324
locale,
@@ -128,6 +129,7 @@ export const find: Find = async function find(
128129
adapter: this,
129130
collection: collectionSlug,
130131
collectionConfig,
132+
draftsEnabled,
131133
joins,
132134
locale,
133135
query,

packages/db-mongodb/src/findOne.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { transform } from './utilities/transform.js'
1414

1515
export const findOne: FindOne = async function findOne(
1616
this: MongooseAdapter,
17-
{ collection: collectionSlug, joins, locale, req, select, where = {} },
17+
{ collection: collectionSlug, draftsEnabled, joins, locale, req, select, where = {} },
1818
) {
1919
const { collectionConfig, Model } = getCollection({ adapter: this, collectionSlug })
2020

@@ -42,6 +42,7 @@ export const findOne: FindOne = async function findOne(
4242
adapter: this,
4343
collection: collectionSlug,
4444
collectionConfig,
45+
draftsEnabled,
4546
joins,
4647
locale,
4748
projection,

packages/db-mongodb/src/utilities/buildJoinAggregation.ts

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@ import type { PipelineStage } from 'mongoose'
22

33
import {
44
APIError,
5+
appendVersionToQueryKey,
6+
buildVersionCollectionFields,
57
type CollectionSlug,
8+
combineQueries,
69
type FlattenedField,
10+
getQueryDraftsSort,
711
type JoinQuery,
812
type SanitizedCollectionConfig,
913
} from 'payload'
1014
import { fieldShouldBeLocalized } from 'payload/shared'
1115

1216
import type { MongooseAdapter } from '../index.js'
17+
import type { CollectionModel } from '../types.js'
1318

1419
import { buildQuery } from '../queries/buildQuery.js'
1520
import { buildSortParam } from '../queries/buildSortParam.js'
@@ -19,6 +24,7 @@ type BuildJoinAggregationArgs = {
1924
adapter: MongooseAdapter
2025
collection: CollectionSlug
2126
collectionConfig: SanitizedCollectionConfig
27+
draftsEnabled?: boolean
2228
joins?: JoinQuery
2329
locale?: string
2430
projection?: Record<string, true>
@@ -32,6 +38,7 @@ export const buildJoinAggregation = async ({
3238
adapter,
3339
collection,
3440
collectionConfig,
41+
draftsEnabled,
3542
joins,
3643
locale,
3744
projection,
@@ -262,10 +269,27 @@ export const buildJoinAggregation = async ({
262269
continue
263270
}
264271

265-
const { collectionConfig, Model: JoinModel } = getCollection({
266-
adapter,
267-
collectionSlug: join.field.collection as string,
268-
})
272+
const collectionConfig = adapter.payload.collections[join.field.collection as string]?.config
273+
274+
if (!collectionConfig) {
275+
throw new APIError(
276+
`Collection config for ${join.field.collection.toString()} was not found`,
277+
)
278+
}
279+
280+
let JoinModel: CollectionModel | undefined
281+
282+
const useDrafts = (draftsEnabled || versions) && Boolean(collectionConfig.versions.drafts)
283+
284+
if (useDrafts) {
285+
JoinModel = adapter.versions[collectionConfig.slug]
286+
} else {
287+
JoinModel = adapter.collections[collectionConfig.slug]
288+
}
289+
290+
if (!JoinModel) {
291+
throw new APIError(`Join Model was not found for ${collectionConfig.slug}`)
292+
}
269293

270294
const {
271295
count,
@@ -279,12 +303,16 @@ export const buildJoinAggregation = async ({
279303
throw new Error('Unreachable')
280304
}
281305

306+
const fields = useDrafts
307+
? buildVersionCollectionFields(adapter.payload.config, collectionConfig, true)
308+
: collectionConfig.flattenedFields
309+
282310
const sort = buildSortParam({
283311
adapter,
284312
config: adapter.payload.config,
285-
fields: collectionConfig.flattenedFields,
313+
fields,
286314
locale,
287-
sort: sortJoin,
315+
sort: useDrafts ? getQueryDraftsSort({ collectionConfig, sort: sortJoin }) : sortJoin,
288316
timestamps: true,
289317
})
290318
const sortProperty = Object.keys(sort)[0]!
@@ -293,7 +321,13 @@ export const buildJoinAggregation = async ({
293321
const $match = await JoinModel.buildQuery({
294322
locale,
295323
payload: adapter.payload,
296-
where: whereJoin,
324+
where: useDrafts
325+
? combineQueries(appendVersionToQueryKey(whereJoin), {
326+
latest: {
327+
equals: true,
328+
},
329+
})
330+
: whereJoin,
297331
})
298332

299333
const pipeline: Exclude<PipelineStage, PipelineStage.Merge | PipelineStage.Out>[] = [
@@ -345,6 +379,12 @@ export const buildJoinAggregation = async ({
345379
},
346380
)
347381

382+
let foreignFieldPrefix = ''
383+
384+
if (useDrafts) {
385+
foreignFieldPrefix = 'version.'
386+
}
387+
348388
if (adapter.payload.config.localization && locale === 'all') {
349389
adapter.payload.config.localization.localeCodes.forEach((code) => {
350390
const as = `${versions ? `version.${join.joinPath}` : join.joinPath}${code}`
@@ -353,7 +393,7 @@ export const buildJoinAggregation = async ({
353393
{
354394
$lookup: {
355395
as: `${as}.docs`,
356-
foreignField: `${join.field.on}${code}${polymorphicSuffix}`,
396+
foreignField: `${foreignFieldPrefix}${join.field.on}${code}${polymorphicSuffix}`,
357397
from: JoinModel.collection.name,
358398
localField: versions ? 'parent' : '_id',
359399
pipeline,
@@ -364,7 +404,7 @@ export const buildJoinAggregation = async ({
364404
[`${as}.docs`]: {
365405
$map: {
366406
as: 'doc',
367-
in: '$$doc._id',
407+
in: useDrafts ? `$$doc.parent` : '$$doc._id',
368408
input: `$${as}.docs`,
369409
},
370410
}, // Slicing the docs to match the limit
@@ -387,7 +427,10 @@ export const buildJoinAggregation = async ({
387427
}
388428

389429
if (count) {
390-
addTotalDocsAggregation(as, `${join.field.on}${code}${polymorphicSuffix}`)
430+
addTotalDocsAggregation(
431+
as,
432+
`${foreignFieldPrefix}${join.field.on}${code}${polymorphicSuffix}`,
433+
)
391434
}
392435
})
393436
} else {
@@ -414,7 +457,7 @@ export const buildJoinAggregation = async ({
414457
{
415458
$lookup: {
416459
as: `${as}.docs`,
417-
foreignField,
460+
foreignField: `${foreignFieldPrefix}${foreignField}`,
418461
from: JoinModel.collection.name,
419462
localField: versions ? 'parent' : '_id',
420463
pipeline,
@@ -425,7 +468,7 @@ export const buildJoinAggregation = async ({
425468
[`${as}.docs`]: {
426469
$map: {
427470
as: 'doc',
428-
in: '$$doc._id',
471+
in: useDrafts ? `$$doc.parent` : '$$doc._id',
429472
input: `$${as}.docs`,
430473
},
431474
}, // Slicing the docs to match the limit
@@ -437,7 +480,7 @@ export const buildJoinAggregation = async ({
437480
)
438481

439482
if (count) {
440-
addTotalDocsAggregation(as, foreignField)
483+
addTotalDocsAggregation(as, `${foreignFieldPrefix}${foreignField}`)
441484
}
442485

443486
if (limitJoin > 0) {

packages/drizzle/src/find.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,19 @@ import { findMany } from './find/findMany.js'
88

99
export const find: Find = async function find(
1010
this: DrizzleAdapter,
11-
{ collection, joins, limit, locale, page = 1, pagination, req, select, sort: sortArg, where },
11+
{
12+
collection,
13+
draftsEnabled,
14+
joins,
15+
limit,
16+
locale,
17+
page = 1,
18+
pagination,
19+
req,
20+
select,
21+
sort: sortArg,
22+
where,
23+
},
1224
) {
1325
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
1426
const sort = sortArg !== undefined && sortArg !== null ? sortArg : collectionConfig.defaultSort
@@ -18,6 +30,7 @@ export const find: Find = async function find(
1830
return findMany({
1931
adapter: this,
2032
collectionSlug: collectionConfig.slug,
33+
draftsEnabled,
2134
fields: collectionConfig.flattenedFields,
2235
joins,
2336
limit,

packages/drizzle/src/find/buildFindManyArgs.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ type BuildFindQueryArgs = {
1111
adapter: DrizzleAdapter
1212
collectionSlug?: string
1313
depth: number
14+
draftsEnabled?: boolean
1415
fields: FlattenedField[]
1516
joinQuery?: JoinQuery
1617
/**
@@ -35,6 +36,7 @@ export const buildFindManyArgs = ({
3536
adapter,
3637
collectionSlug,
3738
depth,
39+
draftsEnabled,
3840
fields,
3941
joinQuery,
4042
joins = [],
@@ -80,6 +82,7 @@ export const buildFindManyArgs = ({
8082
currentArgs: result,
8183
currentTableName: tableName,
8284
depth,
85+
draftsEnabled,
8386
fields,
8487
joinQuery,
8588
joins,

packages/drizzle/src/find/findMany.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type Args = {
2222
export const findMany = async function find({
2323
adapter,
2424
collectionSlug,
25+
draftsEnabled,
2526
fields,
2627
joins: joinQuery,
2728
limit: limitArg,
@@ -74,6 +75,7 @@ export const findMany = async function find({
7475
adapter,
7576
collectionSlug,
7677
depth: 0,
78+
draftsEnabled,
7779
fields,
7880
joinQuery,
7981
joins,

0 commit comments

Comments
 (0)