Digamos que estamos construyendo nuestras primeras entidades para una nueva aplicación web. Hay una entidad para los usuarios :
@Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column() username: string; @Column() password: string; @OneToOne(() => Author) author: Author;Los usuarios pueden ser Autores después del registro. Así que hay una relación de uno a uno entre los usuarios y la tabla de autores. Digamos que tenemos otra tabla llamada libros , un autor puede tener varios libros.
export class Author { @PrimaryGeneratedColumn() id: number; @Column() Name: string; @OneToMany(() => Book, (Book) => Book.Author) Book: Book[]; @OneToOne(() => User) @JoinColumn() User: User;Aquí hay una entidad de muestra para el repositorio de Libros:
export class Book { @PrimaryGeneratedColumn() id: number; @Column() Name: string; @Column() ISIN: string; @OneToOne(() => Author) @JoinColumn() Author: Author;La pregunta es, cuando migramos estas entidades y construimos nuestra primera base de datos limpia , ¿cómo podemos insertar los datos a través de la API de llamadas? Un servicio de muestra para el método API Post:
@Injectable() export class BookService { constructor( @InjectRepository(Book) private BookRepository: Repository<Book>, ) {} async create(createBookDto: CreateBookDto) { await this.BookRepository.insert(createBookDto); } }Y el controlador:
@Controller('books') export class BookController { constructor(private readonly BookService: BookService) {} @Post('/Book') create(@Body() createBookDto: CreateBookDto) { return this.BookService.create(createBookDto); } } El problema aquí es que cuando quiero crear un nuevo libro publicando datos en la ruta API, necesita que se defina el Autor. Entonces, ¿cómo puedo publicar datos de autores de libros de usuarios existentes en la base de datos a través de este servicio?
La mejor opción en la que pienso es crear una nueva instancia de las clases , obtener los datos de la solicitud @Body y asignarlos a los objetos de la clase y luego guardarlos en la base de datos.
Pero creo que no es una buena solución, ya que es muy preferible usar repositorios en lugar de tipo de clase de objeto.
Creo que cometes un error en la definición de tu entidad. Existe una relación OneToMany entre el autor y el libro.
Modifica la entidad de tu libro de esta manera
export class Book { @PrimaryGeneratedColumn() id: number; @Column() Name: string; @Column() ISIN: string; @ManyToOne(() => Author, author=> author.book, { nullable: true }) @JoinColumn() Author: Author; { nullable: true } esto le permitirá guardar los datos de su libro sin tener un autor.
Modifica tu servicio para guardar la información del libro
public async create(createBookDTO: CreateBookDTO) { try { if ( createBookDTO.hasOwnProperty('author') && createTaskDTO.author ) { const author = await this.connection.manager.findOne(Author, { where: { id: createBookDTO.author, }, }); if (author) { createBookDTO.author = author; } else { throw new NotAcceptableException('Author not found'); } } return await this.bookRepo.save(createBookDTO); } catch (err) { throw new HttpException(err, err.status || HttpStatus.BAD_REQUEST); } }