Open paulKabira opened 4 years ago
Duplicate of the following:
@zMotivat0r might be a good idea to add some breaking changes note in the change log?
@paulKabira have you tried using aliases for relations? It should do the thing
Yes. I have tried using alias for the relations, they are not found, this is only the case for relation inside the embedded entities.
I checked the code and found that when I join a nested embedded entity, The getRelationMetadata
does not get the nested metadata if the join is in an embedded embedded relation. Since I was in a hurry, I wrote a quick and dirty fix, maybe this can help better understand the problem better. Most of the code is copied from the parent method.. Only thing is alias
is always required.
export class TypeormCrudDelete<T extends { updatedBy: UserDto }> extends TypeOrmCrudService<T> {
/**
* Support for soft delete with auth persist until
* the library releases one.
* TODO: Update after release
*/
async deleteOne(req: CrudRequest): Promise<void | T> {
const { returnDeleted } = req.options.routes.deleteOneBase;
const entity = await super.getOneOrFail(req);
const deleted = await this.repo.manager.transaction(async manager => {
const toDelete = await manager.save(Object.assign(entity, req.parsed.authPersist));
return await manager.softRemove(toDelete);
});
return returnDeleted ? plainToClass(this.entityType, { ...deleted }) : undefined;
}
/**
* Check if the property path is inside a embedded entity.
* TODO: Add better check detection/Remove after issue resolved
* @param propertyPath The enitity property path
*/
isEmbedded(propertyPath: string) {
const [prefix] = propertyPath.split('.');
return this.repo.metadata.embeddeds.some(e => e.propertyName === prefix);
}
/**
* Dirty fix for embedded relations.
* NOTE: Check parent for the logic copypasta.
* TODO: Update after issue is resolved.
*/
getRelationMetadata(field: string, options: JoinOption): IAllowedRelation {
const relation = super.getRelationMetadata(field, options);
const fields = field.split('.');
if (this.isEmbedded(field) && !relation && fields.length > 1) {
let relationMetadata: EntityMetadata;
let name: string;
let path: string;
let allowedRelation: IAllowedRelation;
const reduced = fields.reduce(
(res, propertyName) => {
const found = res.relations.length
? res.relations.find(one => one.propertyName === propertyName)
: null;
const relationMetadata = found ? found.inverseEntityMetadata : null;
const relations = relationMetadata ? relationMetadata.relations : res.relations;
name = propertyName;
path = found ? found.propertyPath : '';
return {
relations,
relationMetadata,
};
},
{
relations: this.repo.metadata.relations,
relationMetadata: null,
},
);
relationMetadata = reduced.relationMetadata;
if (relationMetadata) {
const { columns, primaryColumns } = this.getEntityColumns(relationMetadata);
allowedRelation = {
alias: options.alias,
name,
path: `${this.alias}.${path}`,
columns,
nested: false,
primaryColumns,
} as IAllowedRelation;
}
if (allowedRelation) {
const allowedColumns = this.getAllowedColumns(allowedRelation.columns, options);
const toSave = { ...allowedRelation, allowedColumns };
this.entityRelationsHash.set(field, toSave);
if (options.alias) {
this.entityRelationsHash.set(options.alias, toSave);
}
return toSave;
}
}
return relation;
}
}
First of all, I have been using this library for many projects and it reduces the development time drastically. I really appreciate the hard work you have put on this.
I have encountered an error when I try to join a relation inside embedded entity. I cannot seem to do it.
Thanks for your help.