Search code examples
postgresqlnestjsmikro-orm

Nested populate not working for mikro-orm


I'm using mikro-orm with nest.js, I have Users, Roles and Permissions entities. I need to select user by id with it's role and permissions from database. I'm using the following code to select user with everything:

this._userRepo.findOne({ $or: [{ email }] }, { populate: ['role', 'role.permissions'] }) 

I need the result to look like the following code example, but permissions are not selected:

{
    id: 1,
    email: 'john.doe@inter.net',
    firstName: 'john',
    lastName: 'Doe',
    ...
    role: {
        id: 21,
        name: 'Moderator',
        permissions: [
            { id: 1, name: 'Create' },
            { id: 2, name: 'Update' },
            { id: 3, name: 'Delete' },
        ]
    }
}

Here's how my entities and schema looks like:

// user.entity.ts
@Entity({ tableName: 'users' })
export class UserEntity {
    @PrimaryKey() id: number;
    @Property() email: string;
    @Property() firstName: string;
    @Property() lastName: string;    
    ...
    @ManyToOne(() => RoleEntity) role: ref<RoleEntity, 'id'>;

    constructor(role: RoleEntity) {
        this.role = ref(role);
    }
}

// role.entity.ts
@Entity({ tableName: 'roles' })
export class RoleEntity {
    @PrimaryKey() id: number;
    @Property() name: string;
    ...
    @ManyToMany(() => PermissionEntity) permissions = new Collection<PermissionEntity>(this);
}

// permission.entity.ts
@Entity({ tableName: 'permissions' })
export class PermissionEntity {
    @PrimaryKey() id: number;
    @Property() name: string;
}

And there's roles_permissions table generated in database:

|role_entity_id|permission_entity_id|
|--------------|--------------------|
|     1        |          1         |

How can I solve this issue?


Solution

  • After torturing for several hours, I found that I was missing some properties to be specified in @ManyToMany relation. So, I changed my RoleEntity to:

    @Entity({ tableName: 'roles' })
    export class RoleEntity {
        @PrimaryKey() id: number;
        @Property() name: string;
        ...
        @ManyToMany({ 
            entity: () => PermissionEntity,
            owner: true,
            pivotTable: 'roles_permissions',
            joinColumn: 'role_entity_id',
            inverseJoinColumn: 'permission_entity_id',
            hidden: true,
        })
        permissions = new Collection<PermissionEntity>(this);
    }
    

    And now I can select role with it's permissions from database.