NestJS: как получить доступ к базе данных в прослушивателях сущностей?

#javascript #node.js #typescript #nestjs #typeorm

#javascript #node.js #typescript #nestjs #typeorm

Вопрос:

У меня есть @BeforeInsert() слушатель в моей Post сущности. Предполагается, что прослушиватель должен создать уникальный slug фрагмент для столбца перед вставкой.

Например:

 export class Post extends BaseEntity {
    @PrimaryGeneratedColumn()
    id: number

    @Column()
    title: string

    @Column()
    slug: string

    @BeforeInsert()
    private updateSlug() {
        this.slug = slugify(this.title)
        // I will need to access the database to check whether the same slug has existsed already or not. 
        // How do I access the database in this listener method?
    }
}
  

Поскольку slug предполагается, что столбец уникален, мне нужно будет проверить в базе данных, чтобы узнать, существует ли тот же slug уже. Если пуля уже существует, мне нужно будет добавить число позади пули, например hello-word-1 .

Однако для этого мне нужно будет получить доступ к Post репозиторию сущности в Post классе сущностей, прежде чем я смогу получить доступ к базе данных. Но я не вижу, как я могу внедрить репозиторий в свой Post класс сущностей для доступа к базе данных для этой цели.

Как мне подойти к этой проблеме?

Комментарии:

1. Вы не должны обращаться к репозиторию из своей сущности, но вы можете предоставить API в пользовательском репозитории, чтобы делать то, что вам нужно, поскольку вы можете получить entity manager оттуда. Затем вы просто вызываете репозиторий из своей кодовой базы, когда вам нужно. На мой взгляд, проверять slug перед вставкой слишком поздно, это то, что вы должны сделать заранее.

Ответ №1:

Насколько я знаю, невозможно использовать внедрение зависимостей в сущности typeorm, поскольку они не создаются nest. Однако вместо этого вы можете использовать EntitySubscriber, который может вводить зависимости. Смотрите Решение этой проблемы на Github:

 import { Injectable } from '@nestjs/common';
import { InjectConnection, InjectRepository } from '@nestjs/typeorm';
import { Connection, EntitySubscriberInterface, InsertEvent, Repository } from 'typeorm';
import { Post } from '../models';

@Injectable()
export class PostSubscriber implements EntitySubscriberInterface {

  constructor(
    @InjectConnection() readonly connection: Connection,
    // Inject your repository here
    @InjectRepository(Photo) private readonly postRepository: Repository<Post>,
  ) {
    connection.subscribers.push(this);
  }

  listenTo() {
    return Post;
  }

  beforeInsert(event: InsertEvent<Post>) {
    // called before insert
  };

}
  

Комментарии:

1. Как я могу сделать то же самое, чтобы внедрить любую службу? В этом примере используется только @InjectConnection и @InjectRepository . Я пытался @Inject() public myService MyService , но это оказалось undefined .

2. Вы пытались добавить PostSubscriber класс в массив providers вашего модуля?