diff --git a/packages/db-postgres/src/queries/getTableColumnFromPath.ts b/packages/db-postgres/src/queries/getTableColumnFromPath.ts index ac86d6b34..08e083f81 100644 --- a/packages/db-postgres/src/queries/getTableColumnFromPath.ts +++ b/packages/db-postgres/src/queries/getTableColumnFromPath.ts @@ -360,13 +360,32 @@ export const getTableColumnFromPath = ({ ) // Join in the relationships table - joinAliases.push({ - condition: and( - eq((aliasTable || adapter.tables[rootTableName]).id, aliasRelationshipTable.parent), - like(aliasRelationshipTable.path, `${constraintPath}${field.name}`), - ), - table: aliasRelationshipTable, - }) + if (locale && field.localized && adapter.payload.config.localization) { + joinAliases.push({ + condition: and( + eq((aliasTable || adapter.tables[rootTableName]).id, aliasRelationshipTable.parent), + eq(aliasRelationshipTable.locale, locale), + like(aliasRelationshipTable.path, `${constraintPath}${field.name}`), + ), + table: aliasRelationshipTable, + }) + if (locale !== 'all') { + constraints.push({ + columnName: 'locale', + table: aliasRelationshipTable, + value: locale, + }) + } + } else { + // Join in the relationships table + joinAliases.push({ + condition: and( + eq((aliasTable || adapter.tables[rootTableName]).id, aliasRelationshipTable.parent), + like(aliasRelationshipTable.path, `${constraintPath}${field.name}`), + ), + table: aliasRelationshipTable, + }) + } selectFields[`${relationTableName}.path`] = aliasRelationshipTable.path diff --git a/test/relationships/config.ts b/test/relationships/config.ts index 6b5cf083a..81a312a69 100644 --- a/test/relationships/config.ts +++ b/test/relationships/config.ts @@ -10,6 +10,7 @@ import { polymorphicRelationshipsSlug, relationSlug, slug, + slugWithLocalizedRel, treeSlug, } from './shared.js' @@ -47,6 +48,10 @@ const collectionWithName = (collectionSlug: string): CollectionConfig => { } export default buildConfigWithDefaults({ + localization: { + locales: ['en', 'de'], + defaultLocale: 'en', + }, collections: [ { slug, @@ -109,6 +114,23 @@ export default buildConfigWithDefaults({ }, ], }, + { + slug: slugWithLocalizedRel, + access: openAccess, + fields: [ + { + name: 'title', + type: 'text', + }, + // Relationship + { + name: 'relationField', + type: 'relationship', + relationTo: relationSlug, + localized: true, + }, + ], + }, collectionWithName(relationSlug), { ...collectionWithName(defaultAccessRelSlug), diff --git a/test/relationships/int.spec.ts b/test/relationships/int.spec.ts index a6a65aa71..571b5d3fa 100644 --- a/test/relationships/int.spec.ts +++ b/test/relationships/int.spec.ts @@ -10,6 +10,7 @@ import type { CustomIdRelation, Director, Post, + PostsLocalized, Relation, } from './payload-types.js' @@ -23,6 +24,7 @@ import { polymorphicRelationshipsSlug, relationSlug, slug, + slugWithLocalizedRel, treeSlug, usersSlug, } from './shared.js' @@ -517,6 +519,85 @@ describe('Relationships', () => { expect(doc?.relationField).toMatchObject({ id: relation.id, name: relation.name }) }) }) + + describe('with localization', () => { + let relation1: Relation + let relation2: Relation + let localizedPost1: PostsLocalized + let localizedPost2: PostsLocalized + + beforeAll(async () => { + relation1 = await payload.create({ + collection: relationSlug, + data: { + name: 'english', + }, + }) + + relation2 = await payload.create({ + collection: relationSlug, + data: { + name: 'german', + }, + }) + + localizedPost1 = await payload.create<'postsLocalized'>({ + collection: slugWithLocalizedRel, + data: { + title: 'english', + relationField: relation1.id, + }, + locale: 'en', + }) + + await payload.update({ + id: localizedPost1.id, + collection: slugWithLocalizedRel, + locale: 'de', + data: { + relationField: relation2.id, + }, + }) + + localizedPost2 = await payload.create({ + collection: slugWithLocalizedRel, + data: { + title: 'german', + relationField: relation2.id, + }, + locale: 'de', + }) + }) + it('should find two docs for german locale', async () => { + const { docs } = await payload.find({ + collection: slugWithLocalizedRel, + locale: 'de', + where: { + relationField: { + equals: relation2.id, + }, + }, + }) + + const mappedIds = docs.map((doc) => doc?.id) + expect(mappedIds).toContain(localizedPost1.id) + expect(mappedIds).toContain(localizedPost2.id) + }) + + it("shouldn't find a relationship query outside of the specified locale", async () => { + const { docs } = await payload.find({ + collection: slugWithLocalizedRel, + locale: 'en', + where: { + relationField: { + equals: relation2.id, + }, + }, + }) + + expect(docs.map((doc) => doc?.id)).not.toContain(localizedPost2.id) + }) + }) }) describe('Nested Querying', () => { diff --git a/test/relationships/payload-types.ts b/test/relationships/payload-types.ts index 5be831cc3..ab6fabea8 100644 --- a/test/relationships/payload-types.ts +++ b/test/relationships/payload-types.ts @@ -8,6 +8,7 @@ export interface Config { collections: { posts: Post + postsLocalized: PostsLocalized relation: Relation 'strict-access': StrictAccess 'chained-relation': ChainedRelation @@ -35,6 +36,13 @@ export interface Post { updatedAt: string createdAt: string } +export interface PostsLocalized { + id: string + title?: string | null + relationField?: (string | null) | Relation + updatedAt: string + createdAt: string +} export interface Relation { id: string name?: string diff --git a/test/relationships/shared.ts b/test/relationships/shared.ts index e29e44f45..037e2fd81 100644 --- a/test/relationships/shared.ts +++ b/test/relationships/shared.ts @@ -1,5 +1,6 @@ export const usersSlug = 'users' export const slug = 'posts' +export const slugWithLocalizedRel = 'postsLocalized' export const relationSlug = 'relation' export const defaultAccessRelSlug = 'strict-access' export const chainedRelSlug = 'chained'