书店练习。可以为一个Book
分配一个Genre
尝试使用DTO中提供的genreId
分配一本新书。
@EntityRepository(Book)
export class BookRepository extends Repository<Book> {
constructor(
private genreService: GenresService,
) {
super();
}
async createBook(createBookDto: CreateBookDto): Promise<Book> {
const genre = await this.genreService.getOne(createBookDto.genreId);
const newBook = this.create({
...createBookDto,
genre,
});
return newBook.save();
}
}
@Injectable()
export class GenresService {
constructor(
@InjectRepository(GenreRepository) private readonly genreRepository: GenreRepository,
) {}
async getOne(id: number): Promise<Genre> {
return this.getById(id);
}
private async getById(id: number): Promise<Genre> {
const found = await this.genreRepository.findOne(id);
if (!found) {
throw new NotFoundException(`Genre with id ${id} not found.`);
}
return found;
}
}
BookRepository和GenreRepository由BookstoreModule
一起导入,就像这样:
imports: [
TypeOrmModule.forFeature([
GenreRepository,
BookRepository,
AuthorRepository,
]),
// ...etc
},
NestJS吐出以下错误:
[ExceptionsHandler] this.genreService.getOne is not a function +1045981ms
TypeError: this.genreService.getOne is not a function
at BookRepository.createBook (/Users/artur/Code/Sandbox/books-nest/dist/bookstore/books/book.repository.js:21:47)
at BooksService.createBook (/Users/artur/Code/Sandbox/books-nest/dist/bookstore/books/books.service.js:29:36)
at BooksController.create (/Users/artur/Code/Sandbox/books-nest/dist/bookstore/books/books.controller.js:31:33)
试图注入GenreRepository into the
BookRepository`
constructor(
@InjectRepository(GenreRepository) private genreRepository: GenreRepository,
){
super();
}
和.findOne()
,错误是:
No metadata for "2" was found. +26884ms
EntityMetadataNotFound: No metadata for "2" was found.
(2是genreId的ID)
不确定我的保存方法是否正确。从BookRepository中查找流派的想法也许是错误的,应该以其他方式解决。如果可以,怎么办?
答案 0 :(得分:1)
对我来说,createBook
方法应该位于BookService
内,BookService
需要注入GenreService,然后您应该从{{1}内部调用genreService.getOne(createBookDto.genreId)
}。
让服务处理数据流imo的业务逻辑/编排更有意义。
我建议尝试使用以下代码:
BookService
@Injectable()
export class BookService {
constructor(
@InjectRepository(BookRepository) private readonly bookRepository: BookRepository,
private genreService: GenreService // <= here you go, you inject the genreService into the bookService to take advantage of its methods
) {}
async getOne(id: number): Promise<Genre> {
return this.getById(id);
}
async createBook(createBookDto: CreateBookDto): Promise<Book> {
const genre = await this.genreService.getOne(createBookDto.genreId);
const newBook = this.create({
...createBookDto,
genre,
});
return newBook.save();
}
private async getById(id: number): Promise<Genre> {
const found = await this.bookRepository.findOne(id);
if (!found) {
throw new NotFoundException(`Book with id ${id} not found.`);
}
return found;
}
}
@EntityRepository(Book)
export class BookRepository extends Repository<Book> {}
@Injectable()
export class GenresService {
constructor(
@InjectRepository(GenreRepository) private readonly genreRepository: GenreRepository,
) {}
async getOne(id: number): Promise<Genre> {
return this.getById(id);
}
private async getById(id: number): Promise<Genre> {
const found = await this.genreRepository.findOne(id);
if (!found) {
throw new NotFoundException(`Genre with id ${id} not found.`);
}
return found;
}
}
让我知道是否有帮助:)