From 95266170a6db8065144ac50772f478971d705cd9 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Thu, 23 Oct 2025 16:35:47 +0400 Subject: [PATCH] Resolve one to many relations in DataSource records --- .../core/src/data_sources/model/DataSource.ts | 14 +++++++++--- packages/core/src/data_sources/types.ts | 3 +++ .../specs/data_sources/model/DataSource.ts | 22 ++++++++++++++++++- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/packages/core/src/data_sources/model/DataSource.ts b/packages/core/src/data_sources/model/DataSource.ts index 4e816f429..d2a4ea3be 100644 --- a/packages/core/src/data_sources/model/DataSource.ts +++ b/packages/core/src/data_sources/model/DataSource.ts @@ -194,11 +194,19 @@ export default class DataSource r.attributes[targetField] === relationValue); - if (relatedRecord) { - result[fieldName] = relatedRecord.attributes; + if (fieldSchema.isMany) { + const relationValues = Array.isArray(relationValue) ? relationValue : [relationValue]; + const relatedRecords = targetRecords.filter((r) => relationValues.includes(r.attributes[targetField])); + result[fieldName] = relatedRecords.map((r) => ({ ...r.attributes })); + } else { + const relatedRecord = targetDs.records.find((r) => r.attributes[targetField] === relationValue); + + if (relatedRecord) { + result[fieldName] = { ...relatedRecord.attributes }; + } } } } diff --git a/packages/core/src/data_sources/types.ts b/packages/core/src/data_sources/types.ts index 691e000ee..cc65b76c8 100644 --- a/packages/core/src/data_sources/types.ts +++ b/packages/core/src/data_sources/types.ts @@ -100,6 +100,9 @@ export interface DataFieldSchemaRelation extends DataFieldSchemaBase { * The target field in the data source */ targetField?: string; + /** + * If true, the relation is one-to-many + */ isMany?: boolean; } diff --git a/packages/core/test/specs/data_sources/model/DataSource.ts b/packages/core/test/specs/data_sources/model/DataSource.ts index 0dc2c01ca..d26f39710 100644 --- a/packages/core/test/specs/data_sources/model/DataSource.ts +++ b/packages/core/test/specs/data_sources/model/DataSource.ts @@ -87,15 +87,17 @@ describe('DataSource', () => { const categoryRecords = [ { id: 'cat1', uid: 'cat1-uid', name: 'Category 1' }, { id: 'cat2', uid: 'cat2-uid', name: 'Category 2' }, + { id: 'cat3', uid: 'cat3-uid', name: 'Category 3' }, ]; const userRecords = [ { id: 'user1', username: 'user_one' }, { id: 'user2', username: 'user_two' }, + { id: 'user3', username: 'user_three' }, ]; const blogRecords = [ { id: 'blog1', title: 'First Blog', author: 'user1', categories: ['cat1-uid'] }, { id: 'blog2', title: 'Second Blog', author: 'user2' }, - { id: 'blog3', title: 'Third Blog', categories: ['cat1-uid', 'cat2-uid'] }, + { id: 'blog3', title: 'Third Blog', categories: ['cat1-uid', 'cat3-uid'] }, ]; beforeEach(() => { @@ -137,6 +139,24 @@ describe('DataSource', () => { blogRecords[2], ]); }); + + test('return 1:many resolved values', () => { + const blogsDS = dsm.get('blogs'); + blogsDS.upSchema({ + categories: { + type: DataFieldPrimitiveType.relation, + target: 'categories', + targetField: 'uid', + isMany: true, + }, + }); + const records = blogsDS.getResolvedRecords(); + expect(records).toEqual([ + { ...blogRecords[0], author: userRecords[0], categories: [categoryRecords[0]] }, + { ...blogRecords[1], author: userRecords[1] }, + { ...blogRecords[2], categories: [categoryRecords[0], categoryRecords[2]] }, + ]); + }); }); }); });