Skip to content

Commit ee117bb

Browse files
authored
fix!: handle custom id logic in mongodb adapter (#9069)
### What? Moved the logic for copying the data.id to data._id to the mongoose adapter. ### Why? If you have any hooks that need to set the `id`, the value does not get sent to mongodb as you would expect since it was copied before the beforeValidate hooks. ### How? Now data._id is assigned only in the mongodb adapter's `create` function. BREAKING CHANGES: When using custom ID fields, if you have any collection hooks for beforeValidate, beforeChange then `data._id` will no longer be assigned as this happens now in the database adapter. Use `data.id` instead.
1 parent dc11104 commit ee117bb

File tree

6 files changed

+296
-13
lines changed

6 files changed

+296
-13
lines changed

docs/fields/overview.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ For full details on Admin Options, see the [Field Admin Options](../admin/fields
356356

357357
## Custom ID Fields
358358

359-
All [Collections](../configuration/collections) automatically generate their own ID field. If needed, you can override this behavior by providing an explicit ID field to your config. This will force users to provide a their own ID value when creating a record.
359+
All [Collections](../configuration/collections) automatically generate their own ID field. If needed, you can override this behavior by providing an explicit ID field to your config. This field should either be required or have a hook to generate the ID dynamically.
360360

361361
To define a custom ID field, add a new field with the `name` property set to `id`:
362362

@@ -368,6 +368,7 @@ export const MyCollection: CollectionConfig = {
368368
fields: [
369369
{
370370
name: 'id', // highlight-line
371+
required: true,
371372
type: 'number',
372373
},
373374
],

packages/db-mongodb/src/create.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ export const create: Create = async function create(
2020
fields: this.payload.collections[collection].config.fields,
2121
})
2222

23+
if (this.payload.collections[collection].customIDType) {
24+
sanitizedData._id = sanitizedData.id
25+
}
26+
2327
try {
2428
;[doc] = await Model.create([sanitizedData], options)
2529
} catch (error) {

packages/payload/src/collections/operations/create.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,17 +123,6 @@ export const createOperation = async <
123123
await executeAccess({ data, req }, collectionConfig.access.create)
124124
}
125125

126-
// /////////////////////////////////////
127-
// Custom id
128-
// /////////////////////////////////////
129-
130-
if (payload.collections[collectionConfig.slug].customIDType) {
131-
data = {
132-
_id: data.id,
133-
...data,
134-
}
135-
}
136-
137126
// /////////////////////////////////////
138127
// Generate data for all files and sizes
139128
// /////////////////////////////////////

test/database/config.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const filename = fileURLToPath(import.meta.url)
44
const dirname = path.dirname(filename)
55
import type { TextField } from 'payload'
66

7+
import { v4 as uuid } from 'uuid'
8+
79
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
810
import { devUser } from '../credentials.js'
911

@@ -356,6 +358,29 @@ export default buildConfigWithDefaults({
356358
},
357359
],
358360
},
361+
{
362+
slug: 'custom-ids',
363+
fields: [
364+
{
365+
name: 'id',
366+
type: 'text',
367+
admin: {
368+
readOnly: true,
369+
},
370+
hooks: {
371+
beforeChange: [
372+
({ value, operation }) => {
373+
if (operation === 'create') {
374+
return uuid()
375+
}
376+
return value
377+
},
378+
],
379+
},
380+
},
381+
],
382+
versions: { drafts: true },
383+
},
359384
],
360385
globals: [
361386
{

test/database/int.spec.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,19 @@ describe('database', () => {
7575

7676
expect(updated.id).toStrictEqual(created.doc.id)
7777
})
78+
79+
it('should create with generated ID text from hook', async () => {
80+
const doc = await payload.create({
81+
collection: 'custom-ids',
82+
data: {},
83+
})
84+
85+
expect(doc.id).toBeDefined()
86+
})
7887
})
7988

8089
describe('timestamps', () => {
81-
it('should have createdAt and updatedAt timetstamps to the millisecond', async () => {
90+
it('should have createdAt and updatedAt timestamps to the millisecond', async () => {
8291
const result = await payload.create({
8392
collection: 'posts',
8493
data: {

0 commit comments

Comments
 (0)