Skip to content

Commit 9adbbde

Browse files
authored
fix: postgres null value breaks orderable hook (#11997)
When postgres is used and orderable is enabled, payload cannot update the docs to set the order correctly. This is because the sort on postgres pushes `null` values to the top causing unique constraints to error when two documents are updated to the same _order value.
1 parent 8ad22eb commit 9adbbde

File tree

1 file changed

+21
-18
lines changed
  • packages/payload/src/config/orderable

1 file changed

+21
-18
lines changed

packages/payload/src/config/orderable/index.ts

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -106,24 +106,27 @@ export const addOrderableFieldsAndHook = (
106106
collection.hooks.beforeChange = []
107107
}
108108

109-
const orderBeforeChangeHook: BeforeChangeHook = async ({ data, operation, req }) => {
110-
// Only set _order on create, not on update (unless explicitly provided)
111-
if (operation === 'create') {
112-
for (const orderableFieldName of orderableFieldNames) {
113-
if (!data[orderableFieldName]) {
114-
const lastDoc = await req.payload.find({
115-
collection: collection.slug,
116-
depth: 0,
117-
limit: 1,
118-
pagination: false,
119-
req,
120-
select: { [orderableFieldName]: true },
121-
sort: `-${orderableFieldName}`,
122-
})
109+
const orderBeforeChangeHook: BeforeChangeHook = async ({ data, originalDoc, req }) => {
110+
for (const orderableFieldName of orderableFieldNames) {
111+
if (!data[orderableFieldName] && !originalDoc?.[orderableFieldName]) {
112+
console.log('do not enter')
113+
const lastDoc = await req.payload.find({
114+
collection: collection.slug,
115+
depth: 0,
116+
limit: 1,
117+
pagination: false,
118+
req,
119+
select: { [orderableFieldName]: true },
120+
sort: `-${orderableFieldName}`,
121+
where: {
122+
[orderableFieldName]: {
123+
exists: true,
124+
},
125+
},
126+
})
123127

124-
const lastOrderValue = lastDoc.docs[0]?.[orderableFieldName] || null
125-
data[orderableFieldName] = generateKeyBetween(lastOrderValue, null)
126-
}
128+
const lastOrderValue = lastDoc.docs[0]?.[orderableFieldName] || null
129+
data[orderableFieldName] = generateKeyBetween(lastOrderValue, null)
127130
}
128131
}
129132

@@ -163,7 +166,7 @@ export const addOrderableEndpoint = (config: SanitizedConfig) => {
163166
}
164167
if (
165168
typeof target !== 'object' ||
166-
typeof target.id !== 'string' ||
169+
typeof target.id === 'undefined' ||
167170
typeof target.key !== 'string'
168171
) {
169172
return new Response(JSON.stringify({ error: 'target must be an object with id and key' }), {

0 commit comments

Comments
 (0)