fix(drizzle): hasMany joins - localized, limit and schema paths (#8633)
Fixes https://github.com/payloadcms/payload/issues/8630 - Fixes `hasMany: true` and `localized: true` on the foreign field - Adds `limit` to the subquery instead of hardcoded `11`. - Adds the schema path `field.on` to the subquery, without this having 2 or more relationship fields to the same collection breaks joins - Properly checks if the field is `hasMany`
This commit is contained in:
@@ -55,6 +55,12 @@ export const Categories: CollectionConfig = {
|
||||
collection: postsSlug,
|
||||
on: 'categories',
|
||||
},
|
||||
{
|
||||
name: 'hasManyPostsLocalized',
|
||||
type: 'join',
|
||||
collection: postsSlug,
|
||||
on: 'categoriesLocalized',
|
||||
},
|
||||
{
|
||||
name: 'group',
|
||||
type: 'group',
|
||||
|
||||
@@ -29,6 +29,13 @@ export const Posts: CollectionConfig = {
|
||||
relationTo: categoriesSlug,
|
||||
hasMany: true,
|
||||
},
|
||||
{
|
||||
name: 'categoriesLocalized',
|
||||
type: 'relationship',
|
||||
relationTo: categoriesSlug,
|
||||
hasMany: true,
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'group',
|
||||
type: 'group',
|
||||
|
||||
@@ -5,7 +5,7 @@ import { getFileByPath } from 'payload'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import type { NextRESTClient } from '../helpers/NextRESTClient.js'
|
||||
import type { Category, Post } from './payload-types.js'
|
||||
import type { Category, Config, Post } from './payload-types.js'
|
||||
|
||||
import { devUser } from '../credentials.js'
|
||||
import { idToString } from '../helpers/idToString.js'
|
||||
@@ -80,6 +80,7 @@ describe('Joins Field', () => {
|
||||
category: category.id,
|
||||
upload: uploadedImage,
|
||||
categories,
|
||||
categoriesLocalized: categories,
|
||||
group: {
|
||||
category: category.id,
|
||||
camelCaseCategory: category.id,
|
||||
@@ -212,6 +213,89 @@ describe('Joins Field', () => {
|
||||
expect(otherCategoryWithPosts.hasManyPosts.docs[0].title).toBe('test 14')
|
||||
})
|
||||
|
||||
it('should populate joins using find with hasMany localized relationships', async () => {
|
||||
const post_1 = await createPost(
|
||||
{
|
||||
title: `test es localized 1`,
|
||||
categoriesLocalized: [category.id],
|
||||
group: {
|
||||
category: category.id,
|
||||
camelCaseCategory: category.id,
|
||||
},
|
||||
},
|
||||
'es',
|
||||
)
|
||||
|
||||
const post_2 = await createPost(
|
||||
{
|
||||
title: `test es localized 2`,
|
||||
categoriesLocalized: [otherCategory.id],
|
||||
group: {
|
||||
category: category.id,
|
||||
camelCaseCategory: category.id,
|
||||
},
|
||||
},
|
||||
'es',
|
||||
)
|
||||
|
||||
const resultEn = await payload.find({
|
||||
collection: 'categories',
|
||||
where: {
|
||||
id: { equals: category.id },
|
||||
},
|
||||
})
|
||||
const otherResultEn = await payload.find({
|
||||
collection: 'categories',
|
||||
where: {
|
||||
id: { equals: otherCategory.id },
|
||||
},
|
||||
})
|
||||
|
||||
const [categoryWithPostsEn] = resultEn.docs
|
||||
const [otherCategoryWithPostsEn] = otherResultEn.docs
|
||||
|
||||
expect(categoryWithPostsEn.hasManyPostsLocalized.docs).toHaveLength(10)
|
||||
expect(categoryWithPostsEn.hasManyPostsLocalized.docs[0]).toHaveProperty('title')
|
||||
expect(categoryWithPostsEn.hasManyPostsLocalized.docs[0].title).toBe('test 14')
|
||||
expect(otherCategoryWithPostsEn.hasManyPostsLocalized.docs).toHaveLength(8)
|
||||
expect(otherCategoryWithPostsEn.hasManyPostsLocalized.docs[0]).toHaveProperty('title')
|
||||
expect(otherCategoryWithPostsEn.hasManyPostsLocalized.docs[0].title).toBe('test 14')
|
||||
|
||||
const resultEs = await payload.find({
|
||||
collection: 'categories',
|
||||
locale: 'es',
|
||||
where: {
|
||||
id: { equals: category.id },
|
||||
},
|
||||
})
|
||||
const otherResultEs = await payload.find({
|
||||
collection: 'categories',
|
||||
locale: 'es',
|
||||
where: {
|
||||
id: { equals: otherCategory.id },
|
||||
},
|
||||
})
|
||||
|
||||
const [categoryWithPostsEs] = resultEs.docs
|
||||
const [otherCategoryWithPostsEs] = otherResultEs.docs
|
||||
|
||||
expect(categoryWithPostsEs.hasManyPostsLocalized.docs).toHaveLength(1)
|
||||
expect(categoryWithPostsEs.hasManyPostsLocalized.docs[0].title).toBe('test es localized 1')
|
||||
|
||||
expect(otherCategoryWithPostsEs.hasManyPostsLocalized.docs).toHaveLength(1)
|
||||
expect(otherCategoryWithPostsEs.hasManyPostsLocalized.docs[0].title).toBe('test es localized 2')
|
||||
|
||||
// clean up
|
||||
await payload.delete({
|
||||
collection: 'posts',
|
||||
where: {
|
||||
id: {
|
||||
in: [post_1.id, post_2.id],
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('should not error when deleting documents with joins', async () => {
|
||||
const category = await payload.create({
|
||||
collection: 'categories',
|
||||
@@ -499,9 +583,10 @@ describe('Joins Field', () => {
|
||||
})
|
||||
})
|
||||
|
||||
async function createPost(overrides?: Partial<Post>) {
|
||||
async function createPost(overrides?: Partial<Post>, locale?: Config['locale']) {
|
||||
return payload.create({
|
||||
collection: 'posts',
|
||||
locale,
|
||||
data: {
|
||||
title: 'test',
|
||||
...overrides,
|
||||
|
||||
@@ -58,6 +58,7 @@ export interface Post {
|
||||
upload?: (string | null) | Upload;
|
||||
category?: (string | null) | Category;
|
||||
categories?: (string | Category)[] | null;
|
||||
categoriesLocalized?: (string | Category)[] | null;
|
||||
group?: {
|
||||
category?: (string | null) | Category;
|
||||
camelCaseCategory?: (string | null) | Category;
|
||||
@@ -102,6 +103,10 @@ export interface Category {
|
||||
docs?: (string | Post)[] | null;
|
||||
hasNextPage?: boolean | null;
|
||||
} | null;
|
||||
hasManyPostsLocalized?: {
|
||||
docs?: (string | Post)[] | null;
|
||||
hasNextPage?: boolean | null;
|
||||
} | null;
|
||||
group?: {
|
||||
relatedPosts?: {
|
||||
docs?: (string | Post)[] | null;
|
||||
|
||||
Reference in New Issue
Block a user