fix(db-postgres): query has many relationships nested in row fields (#9944) (#9944)

### What?
Querying by nested to rows fields in has many relationships like this:
```ts
const result = await payload.find({
  collection: 'relationship-fields',
  where: {
    'relationToRowMany.title': { equals: 'some-title' },
  },
})
```
Where the related collection:
```ts
const RowFields: CollectionConfig = {
  slug: rowFieldsSlug,
  fields: [
    {
      type: 'row',
      fields: [
        {
          name: 'title',
          label: 'Title within a row',
          type: 'text',
          required: true,
        },
      ],
    },
  ],
}
```

was broken

### Why?
We migrated to use `flattenedFields`, but not in this specific case.
This error would be caught earlier we used `noImplictAny` typescript
rule. https://www.typescriptlang.org/tsconfig/#noImplicitAny which
wouldn't allow us to create variable like this:
```ts
let relationshipFields // relationshipFields is any here
```
Instead, we should write:
```ts
let relationshipFields: FlattenedField[]
```
We should migrate to it and `strictNullChecks` as well.

Fixes https://github.com/payloadcms/payload/issues/9534
This commit is contained in:
Sasha
2024-12-19 05:26:08 +02:00
committed by GitHub
parent 044c22de54
commit eee6432715
4 changed files with 48 additions and 2 deletions

View File

@@ -358,7 +358,7 @@ export const getTableColumnFromPath = ({
const newCollectionPath = pathSegments.slice(1).join('.') const newCollectionPath = pathSegments.slice(1).join('.')
if (Array.isArray(field.relationTo) || field.hasMany) { if (Array.isArray(field.relationTo) || field.hasMany) {
let relationshipFields let relationshipFields: FlattenedField[]
const relationTableName = `${rootTableName}${adapter.relationshipsSuffix}` const relationTableName = `${rootTableName}${adapter.relationshipsSuffix}`
const { const {
newAliasTable: aliasRelationshipTable, newAliasTable: aliasRelationshipTable,
@@ -405,7 +405,7 @@ export const getTableColumnFromPath = ({
newTableName = adapter.tableNameMap.get(toSnakeCase(relationshipConfig.slug)) newTableName = adapter.tableNameMap.get(toSnakeCase(relationshipConfig.slug))
// parent to relationship join table // parent to relationship join table
relationshipFields = relationshipConfig.fields relationshipFields = relationshipConfig.flattenedFields
;({ newAliasTable } = getTableAlias({ adapter, tableName: newTableName })) ;({ newAliasTable } = getTableAlias({ adapter, tableName: newTableName }))
joins.push({ joins.push({

View File

@@ -115,6 +115,17 @@ const RelationshipFields: CollectionConfig = {
minRows: 2, minRows: 2,
type: 'relationship', type: 'relationship',
}, },
{
name: 'relationToRow',
relationTo: 'row-fields',
type: 'relationship',
},
{
name: 'relationToRowMany',
relationTo: 'row-fields',
type: 'relationship',
hasMany: true,
},
], ],
slug: relationshipFieldsSlug, slug: relationshipFieldsSlug,
} }

View File

@@ -453,6 +453,37 @@ describe('Fields', () => {
expect(result.docs).toHaveLength(1) expect(result.docs).toHaveLength(1)
expect(result.docs[0]).toMatchObject(relationshipInArray) expect(result.docs[0]).toMatchObject(relationshipInArray)
}) })
it('should query text in row after relationship', async () => {
const row = await payload.create({
collection: 'row-fields',
data: { title: 'some-title', id: 'custom-row-id' },
})
const textDoc = await payload.create({
collection: 'text-fields',
data: { text: 'asd' },
})
const rel = await payload.create({
collection: 'relationship-fields',
data: {
relationship: { relationTo: 'text-fields', value: textDoc },
relationToRow: row.id,
relationToRowMany: [row.id],
},
})
const result = await payload.find({
collection: 'relationship-fields',
where: {
'relationToRow.title': { equals: 'some-title' },
'relationToRowMany.title': { equals: 'some-title' },
},
})
expect(result.docs[0].id).toBe(rel.id)
expect(result.totalDocs).toBe(1)
})
}) })
describe('timestamps', () => { describe('timestamps', () => {

View File

@@ -1335,6 +1335,8 @@ export interface RelationshipField {
value: string | TextField; value: string | TextField;
}[] }[]
| null; | null;
relationToRow?: (string | null) | RowField;
relationToRowMany?: (string | RowField)[] | null;
updatedAt: string; updatedAt: string;
createdAt: string; createdAt: string;
} }
@@ -2970,6 +2972,8 @@ export interface RelationshipFieldsSelect<T extends boolean = true> {
id?: T; id?: T;
}; };
relationshipWithMinRows?: T; relationshipWithMinRows?: T;
relationToRow?: T;
relationToRowMany?: T;
updatedAt?: T; updatedAt?: T;
createdAt?: T; createdAt?: T;
} }