Skip to content

Commit 308ad79

Browse files
DanRibbenskendelljoseph
authored andcommitted
fix(plugin-search): delete does not also delete the search doc (#12148)
The plugin-search collection uses an `afterDelete` hook to remove search records from the database. Since a deleted document in postgres causes cascade updates for the foreign key, the query for the document by relationship was not returning the record to be deleted. The solution was to change the delete hook to `beforeDelete` for the search enabled collections. This way we purge records before the main document so the search document query can find and delete the record as expected. An alternative solution in #9623 would remove the `req` so the delete query could still find the document, however, this just works outside of transactions which isn't desirable. fixes #9443
1 parent 026004b commit 308ad79

File tree

4 files changed

+29
-53
lines changed

4 files changed

+29
-53
lines changed
Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,28 @@
11
import type { DeleteFromSearch } from '../../types.js'
22

3-
export const deleteFromSearch: DeleteFromSearch = async ({
4-
collection,
5-
doc,
6-
pluginConfig,
7-
req: { payload },
8-
req,
9-
}) => {
10-
const searchSlug = pluginConfig?.searchOverrides?.slug || 'search'
11-
try {
12-
const searchDocQuery = await payload.find({
13-
collection: searchSlug,
14-
depth: 0,
15-
limit: 1,
16-
pagination: false,
17-
req,
18-
where: {
19-
doc: {
20-
equals: {
21-
relationTo: collection.slug,
22-
value: doc.id,
23-
},
24-
},
25-
},
26-
})
3+
export const deleteFromSearch: DeleteFromSearch =
4+
(pluginConfig) =>
5+
async ({ id, collection, req: { payload }, req }) => {
6+
const searchSlug = pluginConfig?.searchOverrides?.slug || 'search'
277

28-
if (searchDocQuery?.docs?.[0]) {
8+
try {
299
await payload.delete({
30-
id: searchDocQuery?.docs?.[0]?.id,
3110
collection: searchSlug,
11+
depth: 0,
3212
req,
13+
where: {
14+
'doc.relationTo': {
15+
equals: collection.slug,
16+
},
17+
'doc.value': {
18+
equals: id,
19+
},
20+
},
21+
})
22+
} catch (err: unknown) {
23+
payload.logger.error({
24+
err,
25+
msg: `Error deleting ${searchSlug} doc.`,
3326
})
3427
}
35-
} catch (err: unknown) {
36-
payload.logger.error({
37-
err,
38-
msg: `Error deleting ${searchSlug} doc.`,
39-
})
4028
}
41-
42-
return doc
43-
}

packages/plugin-search/src/index.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { CollectionAfterChangeHook, CollectionAfterDeleteHook, Config } from 'payload'
1+
import type { CollectionAfterChangeHook, Config } from 'payload'
22

33
import type { SanitizedSearchPluginConfig, SearchPluginConfig } from './types.js'
44

@@ -7,7 +7,6 @@ import { syncWithSearch } from './Search/hooks/syncWithSearch.js'
77
import { generateSearchCollection } from './Search/index.js'
88

99
type CollectionAfterChangeHookArgs = Parameters<CollectionAfterChangeHook>[0]
10-
type CollectionAfterDeleteHookArgs = Parameters<CollectionAfterDeleteHook>[0]
1110

1211
export const searchPlugin =
1312
(incomingPluginConfig: SearchPluginConfig) =>
@@ -67,14 +66,9 @@ export const searchPlugin =
6766
})
6867
},
6968
],
70-
afterDelete: [
71-
...(existingHooks?.afterDelete || []),
72-
async (args: CollectionAfterDeleteHookArgs) => {
73-
await deleteFromSearch({
74-
...args,
75-
pluginConfig,
76-
})
77-
},
69+
beforeDelete: [
70+
...(existingHooks?.beforeDelete || []),
71+
deleteFromSearch(pluginConfig),
7872
],
7973
},
8074
}

packages/plugin-search/src/types.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type {
22
CollectionAfterChangeHook,
3-
CollectionAfterDeleteHook,
3+
CollectionBeforeDeleteHook,
44
CollectionConfig,
55
Field,
66
Locale,
@@ -96,8 +96,4 @@ export type SyncDocArgs = {
9696
// Convert the `collection` arg from `SanitizedCollectionConfig` to a string
9797
export type SyncWithSearch = (Args: SyncWithSearchArgs) => ReturnType<CollectionAfterChangeHook>
9898

99-
export type DeleteFromSearch = (
100-
Args: {
101-
pluginConfig: SearchPluginConfig
102-
} & Parameters<CollectionAfterDeleteHook>[0],
103-
) => ReturnType<CollectionAfterDeleteHook>
99+
export type DeleteFromSearch = (args: SearchPluginConfig) => CollectionBeforeDeleteHook

test/plugin-search/int.spec.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import type { Payload } from 'payload'
2+
13
import path from 'path'
2-
import { NotFound, type Payload } from 'payload'
34
import { wait } from 'payload/shared'
45
import { fileURLToPath } from 'url'
56

@@ -300,8 +301,8 @@ describe('@payloadcms/plugin-search', () => {
300301
collection: 'search',
301302
depth: 0,
302303
where: {
303-
'doc.value': {
304-
equals: page.id,
304+
id: {
305+
equals: results[0].id,
305306
},
306307
},
307308
})

0 commit comments

Comments
 (0)