diff --git a/app/src/data/entities/Entity.ts b/app/src/data/entities/Entity.ts index 3365190..69a8d4a 100644 --- a/app/src/data/entities/Entity.ts +++ b/app/src/data/entities/Entity.ts @@ -165,6 +165,13 @@ export class Entity< return this.getField(name); } + hasField(name: string): boolean; + hasField(field: Field): boolean; + hasField(nameOrField: string | Field): boolean { + const name = typeof nameOrField === "string" ? nameOrField : nameOrField.name; + return this.fields.findIndex((field) => field.name === name) !== -1; + } + getFields(include_virtual: boolean = false): Field[] { if (include_virtual) return this.fields; return this.fields.filter((f) => !f.isVirtual()); diff --git a/app/src/data/entities/query/Repository.ts b/app/src/data/entities/query/Repository.ts index 5234bc4..92e2f2a 100644 --- a/app/src/data/entities/query/Repository.ts +++ b/app/src/data/entities/query/Repository.ts @@ -73,7 +73,6 @@ export class Repository 0) { - throw new InvalidSearchParamsException(`Invalid where field(s): ${invalid.join(", ")}`); + throw new InvalidSearchParamsException( + `Invalid where field(s): ${invalid.join(", ")}` + ).context({ aliases, entity: entity.name }); } validated.where = options.where; @@ -334,7 +335,6 @@ export class Repository): Promise> { const { qb, options } = this.buildQuery(_options); - //console.log("findMany:options", options); await this.emgr.emit( new Repository.Events.RepositoryFindManyBefore({ entity: this.entity, options }) @@ -386,7 +386,6 @@ export class Repository extends Field< } override async transformPersist(value: any): Promise { - throw new Error("This function should not be called"); + throw new Error("PrimaryField: This function should not be called"); } override toJsonSchema() { diff --git a/app/src/data/relations/ManyToManyRelation.ts b/app/src/data/relations/ManyToManyRelation.ts index b4e89f1..f96ab74 100644 --- a/app/src/data/relations/ManyToManyRelation.ts +++ b/app/src/data/relations/ManyToManyRelation.ts @@ -105,13 +105,13 @@ export class ManyToManyRelation extends EntityRelation { - const conn = this.connectionEntity; + const { other, otherRef } = this.getQueryInfo(entity); return { where: { - [`${conn.name}.${entity.name}_${entity.getPrimaryField().name}`]: id + [otherRef]: id }, - join: [this.target.reference] + join: [other.reference] }; } @@ -160,47 +160,27 @@ export class ManyToManyRelation extends EntityRelation) { this.em = em; - //this.connectionEntity.addField(new RelationField(this.source.entity)); - //this.connectionEntity.addField(new RelationField(this.target.entity)); - this.connectionEntity.addField(RelationField.create(this, this.source)); - this.connectionEntity.addField(RelationField.create(this, this.target)); + const sourceField = RelationField.create(this, this.source); + const targetField = RelationField.create(this, this.target); - // @todo: check this - for (const field of this.additionalFields) { - this.source.entity.addField(new VirtualField(this.connectionTableMappedName)); - this.target.entity.addField(new VirtualField(this.connectionTableMappedName)); + if (em.hasEntity(this.connectionEntity)) { + // @todo: also check for correct signatures of field + if (!this.connectionEntity.hasField(sourceField)) { + this.connectionEntity.addField(sourceField); + } + if (!this.connectionEntity.hasField(targetField)) { + this.connectionEntity.addField(targetField); + } + } else { + this.connectionEntity.addField(sourceField); + this.connectionEntity.addField(targetField); + em.addEntity(this.connectionEntity); } - - em.addEntity(this.connectionEntity); } override getName(): string { diff --git a/app/src/data/relations/RelationField.ts b/app/src/data/relations/RelationField.ts index f3d557f..0405ed5 100644 --- a/app/src/data/relations/RelationField.ts +++ b/app/src/data/relations/RelationField.ts @@ -88,7 +88,7 @@ export class RelationField extends Field { } override async transformPersist(value: any, em: EntityManager): Promise { - throw new Error("This function should not be called"); + throw new Error("RelationField: This function should not be called"); } override toJsonSchema() { diff --git a/app/src/data/relations/RelationMutator.ts b/app/src/data/relations/RelationMutator.ts index 3aa85b0..2becd17 100644 --- a/app/src/data/relations/RelationMutator.ts +++ b/app/src/data/relations/RelationMutator.ts @@ -2,6 +2,7 @@ import type { PrimaryFieldType } from "core"; import type { Entity, EntityManager } from "../entities"; import { type EntityRelation, + ManyToManyRelation, type MutationOperation, MutationOperations, RelationField @@ -26,11 +27,26 @@ export class RelationMutator { */ getRelationalKeys(): string[] { const references: string[] = []; + + // if persisting a manytomany connection table + // @todo: improve later + if (this.entity.type === "generated") { + const relation = this.em.relations.all.find( + (r) => r instanceof ManyToManyRelation && r.connectionEntity.name === this.entity.name + ); + if (relation instanceof ManyToManyRelation) { + references.push( + ...this.entity.fields.filter((f) => f.type === "relation").map((f) => f.name) + ); + } + } + this.em.relationsOf(this.entity.name).map((r) => { const info = r.helper(this.entity.name).getMutationInfo(); references.push(info.reference); info.local_field && references.push(info.local_field); }); + return references; } diff --git a/app/src/ui/components/form/Formy/components.tsx b/app/src/ui/components/form/Formy/components.tsx index 18cedf9..34ddcb9 100644 --- a/app/src/ui/components/form/Formy/components.tsx +++ b/app/src/ui/components/form/Formy/components.tsx @@ -72,8 +72,9 @@ export const FieldLabel: React.FC & { field: Field }) => { const desc = field.getDescription(); return ( -