A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

Relaciones uno a uno

18/33
Recursos

Aportes 6

Preguntas 2

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

Buenas, si no quieren colocar a cada entity los campos createAt y updateAt pueden crear una entidad b谩sica que contenga estos atributos:

import { CreateDateColumn, UpdateDateColumn } from 'typeorm';

export class BasicEntity {
  @CreateDateColumn({
    type: 'timestamptz',
    default: () => 'CURRENT_TIMESTAMP',
  })
  createAt: Date;

  @UpdateDateColumn({
    type: 'timestamptz',
    default: () => 'CURRENT_TIMESTAMP',
  })
  updateAt: Date;
}

Y luego extender cada entidad que necesite estos campos:

import { BasicEntity } from 'src/database/base.entity';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User extends BasicEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ type: 'varchar', length: 255 })
  email: string;

  @Column({ type: 'varchar', length: 255 })
  password: string;

  @Column({ type: 'varchar', length: 100 })
  role: string;
}

De esta forma nos ahorramos un poco de tiempo al crear nuestras entidades

Apuntes

Para realizar relaciones 1 a 1 debemos hacer lo siguiente

// src/user/entities/user.entity
@OneToOne(()=>Customer, (customer)=>customer.user, {nullable: true})
@JoinColumn()
customer: Customer;

// src/user/entities/customer.entity
@OneToOne(()=>User, (user)=> user.customer)
user:User;

La entidad que tenga el decorador @JoinColumn es el objeto que creara la llave foranea. Solo una entidad puede tener el decorador @JoinColumn

TypeORM permite tener una relacion bidireccional en las relaciones 1 a 1 sin necesidad de hacer queryes extras.

Lo que hicimos

//src/user/entities/customer.entity
import { Column, CreateDateColumn, Entity, OneToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
import { User } from "./user.entity";

@Entity()
export class Customer {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({type: 'varchar', length: 255})
  name: string;

  @Column({type: 'varchar', length: 255})
  lastName: string;

  @Column({ type: 'varchar', length: 255 })
  phone: string;

  @CreateDateColumn({
    type: 'timestamptz',
    default: () => 'CURRENT_TIMESTAMP',
  })
  createAt: Date;

  @UpdateDateColumn({
    type: 'timestamptz',
    default: () => 'CURRENT_TIMESTAMP',
  })
  updateAt: Date;

  @OneToOne(()=>User, (user)=> user.customer)
  user:User;
}
//src/user/entities/user.entity
import { Column, CreateDateColumn, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
import { Customer } from "./customer.entity";

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ type: 'varchar', length: 255})
  email: string;
  
  @Column({ type: 'varchar', length: 255})
  password: string;

  @Column({ type: 'varchar', length: 255})
  role: string;

  @CreateDateColumn({
    type: 'timestamptz',
    default: () => 'CURRENT_TIMESTAMP'
  })
  createAt: Date;

  @UpdateDateColumn({
    type: 'timestamptz',
    default: () => 'CURRENT_TIMESTAMP',
  })
  updateAt: Date;

  @OneToOne(()=>Customer, (customer)=>customer.user, {nullable: true})
  @JoinColumn()
  customer: Customer;

}
//src/user/services/customer.service
import { Injectable, NotFoundException } from '@nestjs/common';

import { Customer } from '../entities/customer.entity';
import { CreateCustomerDto, UpdateCustomerDto } from '../dtos/customer.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

@Injectable()
export class CustomersService {
  constructor(
    @InjectRepository(Customer) private customerRepo: Repository<Customer>
  ){}

  async findAll() {
    return await this.customerRepo.find()
  }

  async findOne(id: number) {
    const customer = await this.customerRepo.findOne(id);
    if (!customer) {
      throw new NotFoundException(`Customer #${id} not found`);
    }
    return customer;
  }

  create(data: CreateCustomerDto) {
    const newCostumer = this.customerRepo.create(data);
    return this.customerRepo.save(newCostumer);
  }

  async update(id: number, changes: UpdateCustomerDto) {
    const customer = await this.findOne(id);
    this.customerRepo.merge(customer, changes);
    return this.customerRepo.save(customer);
  }

  remove(id: number) {
    return this.customerRepo.delete(id);
  }
}
//src/user/services/user.service
import { Injectable, NotFoundException, Inject } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

import { User } from '../entities/user.entity';
import { Order } from '../entities/order.entity';
import { CreateUserDto, UpdateUserDto } from '../dtos/user.dto';

import { ProductsService } from './../../products/services/products.service';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User) private userRepo: Repository<User>,
    private productsService: ProductsService,
    private configService: ConfigService,
  ) {}

  async findAll() {
    return await this.userRepo.find();
  }

  async findOne(id: number) {
    const user = await this.userRepo.findOne(id);
    if (!user) {
      throw new NotFoundException(`User #${id} not found`);
    }
    return user;
  }

  async create(data: CreateUserDto) {
    const newUser = this.userRepo.create(data);
    return await this.userRepo.save(newUser);
  }

  async update(id: number, changes: UpdateUserDto) {
    const user = await this.findOne(id);
    const updateUser = this.userRepo.merge(user, changes);
    return this.userRepo.save(updateUser);
  }

  remove(id: number) {
    return this.userRepo.delete(id);
  }

  async getOrderByUser(id: number): Promise<Order> {
    const user = await this.userRepo.findOne(id);
    return {
      date: new Date(),
      user,
      products: await this.productsService.findAll(),
    };
  }
}
npm run migrations:generate -- create-user-customer
npm run migrations:run

Vi un comentario que como har铆a para evitar estar repitiendo los campos de CreateAt y UpdateAt sin usar un herencia de clase, investigando un poco me tope con Embedded Entities. Dejo mi ejemplo el cual me funcion贸.

  • Cre茅 un archivo el cual la puse dentro de database.module: 鈥渄ateAt.entity.ts鈥
import { CreateDateColumn, UpdateDateColumn } from 'typeorm';

export class DateAt {
  @CreateDateColumn({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
  createAt: Date;

  @UpdateDateColumn({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
  updateAt: Date;
}
  • En las entidades solo importe este archivo y dentro de column realize una arrow function hacia esta nueva clase.
import { PrimaryGeneratedColumn, Column, Entity } from 'typeorm';
import { DateAt } from '../../database/dateAt.entity';

@Entity()
export class Customer {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ type: 'varchar', length: 100 })
  name: string;

  @Column({ type: 'varchar', length: 100 })
  lastName: string;

  @Column({ type: 'varchar', length: 20 })
  phone: string;

  @Column(() => DateAt)
  register: DateAt;
}

Me funcion贸, incluso corr铆 el comando npm run migrations:generate -- dateAt, el cual no me dio problema alguno.

Podemos configurar ONDELETE y ONUPDATE en nuestras entidades de la siguiente manera:

  @OneToOne(() => Customer, (customer) => customer.user, {
    nullable: true,
    onDelete: 'SET NULL',
    onUpdate: 'CASCADE',
  })
  @JoinColumn()
  customer: Customer;

Recomiendo hacer una entidad base con id, updateAd y createAd. Para que luego extender todas las demas entidades de esta base.
Ej:

import {
  CreateDateColumn,
  PrimaryGeneratedColumn,
  UpdateDateColumn,
} from 'typeorm';

export abstract class BaseEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @CreateDateColumn({
    type: 'timestamp',
    name: 'created_at',
  })
  createdAt: Date;

  @UpdateDateColumn({
    type: 'timestamp',
    name: 'updated_at',
  })
  updatedAt: Date;
}