fix: relations issues (#2497)
* fix: relations issues one-to-one relation not working alias should not be used on the foreignKey side * fix: naming
This commit is contained in:
@ -7,6 +7,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import camelCase from 'lodash.camelcase';
|
||||
|
||||
import { ObjectMetadataService } from 'src/metadata/object-metadata/object-metadata.service';
|
||||
import { FieldMetadataService } from 'src/metadata/field-metadata/field-metadata.service';
|
||||
@ -43,6 +44,19 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Relation types
|
||||
*
|
||||
* MANY TO MANY:
|
||||
* FROM Ǝ-E TO (NOT YET SUPPORTED)
|
||||
*
|
||||
* ONE TO MANY:
|
||||
* FROM --E TO (host the id in the TO table)
|
||||
*
|
||||
* ONE TO ONE:
|
||||
* FROM --- TO (host the id in the TO table)
|
||||
*/
|
||||
|
||||
const objectMetadataEntries =
|
||||
await this.objectMetadataService.findManyWithinWorkspace(
|
||||
[record.fromObjectMetadataId, record.toObjectMetadataId],
|
||||
@ -63,6 +77,8 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
||||
);
|
||||
}
|
||||
|
||||
const foreignKeyColumnName = `${camelCase(record.toName)}Id`;
|
||||
|
||||
const createdFields = await this.fieldMetadataService.createMany([
|
||||
// FROM
|
||||
{
|
||||
@ -84,7 +100,9 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
||||
description: undefined,
|
||||
icon: record.toIcon,
|
||||
isCustom: true,
|
||||
targetColumnMap: {},
|
||||
targetColumnMap: {
|
||||
value: foreignKeyColumnName,
|
||||
},
|
||||
isActive: true,
|
||||
type: FieldMetadataType.RELATION,
|
||||
objectMetadataId: record.toObjectMetadataId,
|
||||
@ -103,10 +121,6 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
||||
toFieldMetadataId: createdFieldMap[record.toObjectMetadataId].id,
|
||||
});
|
||||
|
||||
const foreignKeyColumnName = `${
|
||||
objectMetadataMap[record.fromObjectMetadataId].targetTableName
|
||||
}Id`;
|
||||
|
||||
await this.tenantMigrationService.createCustomMigration(
|
||||
record.workspaceId,
|
||||
[
|
||||
@ -133,6 +147,7 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
||||
referencedTableName:
|
||||
objectMetadataMap[record.fromObjectMetadataId].targetTableName,
|
||||
referencedTableColumnName: 'id',
|
||||
isUnique: record.relationType === RelationMetadataType.ONE_TO_ONE,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@ -21,6 +21,7 @@ export type TenantMigrationColumnRelation = {
|
||||
columnName: string;
|
||||
referencedTableName: string;
|
||||
referencedTableColumnName: string;
|
||||
isUnique?: boolean;
|
||||
};
|
||||
|
||||
export type TenantMigrationColumnAction = {
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { QueryRunner, Table, TableColumn, TableForeignKey } from 'typeorm';
|
||||
import {
|
||||
QueryRunner,
|
||||
Table,
|
||||
TableColumn,
|
||||
TableForeignKey,
|
||||
TableUnique,
|
||||
} from 'typeorm';
|
||||
|
||||
import { TenantMigrationService } from 'src/metadata/tenant-migration/tenant-migration.service';
|
||||
import { TenantDataSourceService } from 'src/tenant-datasource/tenant-datasource.service';
|
||||
@ -217,5 +223,16 @@ export class TenantMigrationRunnerService {
|
||||
onDelete: 'CASCADE',
|
||||
}),
|
||||
);
|
||||
|
||||
// Create unique constraint if for one to one relation
|
||||
if (migrationColumn.isUnique) {
|
||||
await queryRunner.createUniqueConstraint(
|
||||
`${schemaName}.${tableName}`,
|
||||
new TableUnique({
|
||||
name: `UNIQUE_${tableName}_${migrationColumn.columnName}`,
|
||||
columnNames: [migrationColumn.columnName],
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,10 +95,20 @@ export class CompositeFieldAliasFactory {
|
||||
}
|
||||
`;
|
||||
}
|
||||
let relationAlias = fieldKey;
|
||||
|
||||
// For one to one relations, pg_graphql use the targetTableName on the side that is not storing the foreign key
|
||||
// so we need to alias it to the field key
|
||||
if (
|
||||
relationMetadata.relationType === RelationMetadataType.ONE_TO_ONE &&
|
||||
relationDirection === RelationDirection.FROM
|
||||
) {
|
||||
relationAlias = `${fieldKey}: ${referencedObjectMetadata.targetTableName}`;
|
||||
}
|
||||
|
||||
// Otherwise it means it's a relation destination is of kind ONE
|
||||
return `
|
||||
${fieldKey} {
|
||||
${relationAlias} {
|
||||
${this.fieldsStringFactory.createFieldsStringRecursive(
|
||||
info,
|
||||
fieldValue,
|
||||
|
||||
Reference in New Issue
Block a user