SoftwareBrothers / adminjs

AdminJS is an admin panel for apps written in node.js
https://adminjs.co
MIT License
8.17k stars 660 forks source link

Problems with relation and nested resources #1050

Closed KristinaErdman closed 2 years ago

KristinaErdman commented 2 years ago

Hi, I tried to display related resources in the admin panel. NestJs and TypeOrm. Entitties:

import { Entity, Column, PrimaryGeneratedColumn, OneToMany, BaseEntity } from 'typeorm';

import { FeatureValue } from './feature-values';

@Entity({ name: 'feature' })
export class Feature extends BaseEntity{
  @PrimaryGeneratedColumn()
    id: number;

  @Column({ length: 150, unique: true })
    name: string;

  @OneToMany((type) => FeatureValue, (value) => value.feature)
    values: Array<FeatureValue>;
}
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, BaseEntity, RelationId } from 'typeorm';

import { Feature } from '../feature.entity';

@Entity({ name: 'feature_value' })
export class FeatureValue extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  value: string;

  @ManyToOne((type) => Feature, (feature) => feature.values, {
    cascade: true,
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
    nullable: false,
  })
  feature: Feature;

  @RelationId((value: FeatureValue) => value.feature)
  featureId: number;
}

In app.module.ts

import { AdminModule } from '@adminjs/nestjs';
import { Database, Resource } from '@adminjs/typeorm';
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import AdminJS from 'adminjs';

import { Feature, FeatureValue } from './features';

AdminJS.registerAdapter({ Database, Resource })

@Module({
  imports: [
    TypeOrmModule.forRoot(),
    // any modules
    AdminModule.createAdmin({
      adminJsOptions: {
        rootPath: '/admin',
        resources: [
          {
            resource: Feature, options: {
              properties: {
                values: { type: 'mixed' },
              }
            }
          },
          { resource: FeatureValue },
        ]
      }
    }),
  ],
  controllers: [],
  providers: [],
})
export class AppModule { }

Creation and filtering work correctly.

Снимок экрана 2022-03-15 в 11 48 59

But when you browse, you don't see any linked resources.

Снимок экрана 2022-03-15 в 11 57 41 Снимок экрана 2022-03-15 в 11 49 29 Снимок экрана 2022-03-15 в 12 06 32

An error occurs during the update.

Снимок экрана 2022-03-15 в 11 54 24
pratikkapadia5 commented 2 years ago

I am also having the same issue. Followed the same as provided in documentations and added RelationId in ManyToOne but the relationId in AdminJS is empty

dziraf commented 2 years ago

Add @Column() decorator above your foreign key, i. e.:

  @RelationId((value: FeatureValue) => value.feature)
  @Column()
  featureId: number;
KristinaErdman commented 2 years ago

@Column()

Thank you so much! It worked! How can I add related resources to a page? For example, on a Feature page, can I add all the FeatureValues related to it?

Add @Column() decorator above your foreign key, i. e.:

  @RelationId((value: FeatureValue) => value.feature)
  @Column()
  featureId: number;
dziraf commented 2 years ago

1:m and m:n relations are currently not populated by default. I'm trying to figure out how to implement this while supporting different ORMs. Meanwhile, you can create your own custom components and actions to handle that.

KristinaErdman commented 2 years ago

1:m and m:n relations are currently not populated by default. I'm trying to figure out how to implement this while supporting different ORMs. Meanwhile, you can create your own custom components and actions to handle that.

Thank you

lpbonomi commented 1 year ago

1:m and m:n relations are currently not populated by default. I'm trying to figure out how to implement this while supporting different ORMs. Meanwhile, you can create your own custom components and actions to handle that.

Any news on this?

dannicada commented 6 months ago

Add @Column() decorator above your foreign key, i. e.:

  @RelationId((value: FeatureValue) => value.feature)
  @Column()
  featureId: number;

another way to go about it is to add {eager: true} to the relation options (if you don't mind the related entity being loaded as well) like so:

@ManyToOne((type) => Feature, (feature) => feature.values, {
    cascade: true,
    onDelete: 'CASCADE',
    onUpdate: 'CASCADE',
    nullable: false,
    eager: true,
  })
  feature: Feature;

then you can remove "featuredId" entirely if it's not useful in your application logic.

Found this helpful in my case.