Browse Source

Resolve one to many relations in DataSource records

data-source-schema
Artur Arseniev 11 months ago
parent
commit
95266170a6
  1. 14
      packages/core/src/data_sources/model/DataSource.ts
  2. 3
      packages/core/src/data_sources/types.ts
  3. 22
      packages/core/test/specs/data_sources/model/DataSource.ts

14
packages/core/src/data_sources/model/DataSource.ts

@ -194,11 +194,19 @@ export default class DataSource<DRProps extends DataRecordProps = DataRecordProp
if (relationValue) {
const targetDs = this.em.DataSources.get(fieldSchema.target);
if (targetDs) {
const targetRecords = targetDs.records;
const targetField = fieldSchema.targetField || DEF_DATA_FIELD_ID;
const relatedRecord = targetDs.records.find((r) => 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 };
}
}
}
}

3
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;
}

22
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]] },
]);
});
});
});
});

Loading…
Cancel
Save