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.
This commit is contained in:
Dan Ribbens
2025-04-04 14:31:34 -04:00
committed by GitHub
parent 8ad22eb1c0
commit 9adbbde9a8

View File

@@ -106,24 +106,27 @@ export const addOrderableFieldsAndHook = (
collection.hooks.beforeChange = [] collection.hooks.beforeChange = []
} }
const orderBeforeChangeHook: BeforeChangeHook = async ({ data, operation, req }) => { const orderBeforeChangeHook: BeforeChangeHook = async ({ data, originalDoc, req }) => {
// Only set _order on create, not on update (unless explicitly provided) for (const orderableFieldName of orderableFieldNames) {
if (operation === 'create') { if (!data[orderableFieldName] && !originalDoc?.[orderableFieldName]) {
for (const orderableFieldName of orderableFieldNames) { console.log('do not enter')
if (!data[orderableFieldName]) { const lastDoc = await req.payload.find({
const lastDoc = await req.payload.find({ collection: collection.slug,
collection: collection.slug, depth: 0,
depth: 0, limit: 1,
limit: 1, pagination: false,
pagination: false, req,
req, select: { [orderableFieldName]: true },
select: { [orderableFieldName]: true }, sort: `-${orderableFieldName}`,
sort: `-${orderableFieldName}`, where: {
}) [orderableFieldName]: {
exists: true,
},
},
})
const lastOrderValue = lastDoc.docs[0]?.[orderableFieldName] || null const lastOrderValue = lastDoc.docs[0]?.[orderableFieldName] || null
data[orderableFieldName] = generateKeyBetween(lastOrderValue, null) data[orderableFieldName] = generateKeyBetween(lastOrderValue, null)
}
} }
} }
@@ -163,7 +166,7 @@ export const addOrderableEndpoint = (config: SanitizedConfig) => {
} }
if ( if (
typeof target !== 'object' || typeof target !== 'object' ||
typeof target.id !== 'string' || typeof target.id === 'undefined' ||
typeof target.key !== 'string' typeof target.key !== 'string'
) { ) {
return new Response(JSON.stringify({ error: 'target must be an object with id and key' }), { return new Response(JSON.stringify({ error: 'target must be an object with id and key' }), {