typescript - TypeORM inserare rând cu relație one-to-one


Am trei tabele: user, userCareerProfile, userPersonalProfile cu relație @OneToOne.

Entitate Utilizator:

@Entity({ name: 'users' })
export class User extends AbstractEntity {
    @Column({ unique: true })
    email: string;

    @Column({ type: 'varchar', length: 50 })
    full_name: string;

    @OneToOne(() => UserPersonalProfile, (details) => details.user)
    personal_details: UserPersonalProfile;

    @OneToOne(() => UserCareerProfile, (career) => career.user)
    career_profile: UserCareerProfile;

}

Entitate Profil Personal:

@Entity()
export class UserPersonalProfile extends AbstractEntity {

    @Column({ type: 'varchar', length: 20, nullable: true })
    date_of_birth: string;

    @Column({ type: 'varchar', length: 200, nullable: true })
    address: string;

    .....

    @OneToOne(() => User, (user) => user.personal_details, {
        onDelete: 'CASCADE',
    })
    @JoinColumn({ name: 'user_id' })
    user: User;

}

Profil de carieră Entitate:

@Entity()
export class UserCareerProfile extends AbstractEntity {

    @Column({ type: 'varchar', length: 100, nullable: true })
    job_role: string;

    @Column({ type: 'varchar', length: 100, nullable: true })
    work_location: string;

   .....

    @OneToOne(() => User, (user) => user.career_profile, {
        onDelete: 'CASCADE',
    })
    @JoinColumn({ name: 'user_id' })
    user: User;

}

Problemă: Când creez un utilizator nou, se adaugă un rând nou în tabela de utilizatori, dar nu se inserează niciun înregistrare în celelalte două tabele. Cum pot să inser rânduri în cele două tabele pe baza utilizatorului nou creat?

Serviciu pentru utilizatori:

public async createUser(userAttrs: Partial<User>): Promise<User> {
     const user = await this._usersRepository.save(
         this._usersRepository.create({
            ...userAttrs,
         }),
     );

     return user;
}

Răspuns #1

Pe entitatea ta User specifică opțiunea cascade pe decoratoarele @OneToOne(). Poți seta aceasta la true, insert, update, remove, soft-remove sau recover. Alege restricția necesară pentru cazul tău de utilizare. Setarea ei la true sau insert ar trebui să insereze obiectul corespunzător în baza de date.

Aplicați, de asemenea, decoratorul @JoinColumn() pe această parte a relației. Aceasta înseamnă că acest tabel va conține un „id de relație” și o cheie externă către celălalt tabel.

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

    @Column({ unique: true })
    email: string;

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

    @OneToOne(() => Profile, (profile) => profile.user, { cascade: true })
    @JoinColumn()
    profile: Profile;
}

Iată un exemplu de entitate Profile.

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

    @Column({ type: 'varchar', length: 20, nullable: true })
    date_of_birth: string;

    @OneToOne(() => User, (user) => user.profile)
    user: User;
}

Apoi folosește un depozit pentru a salva o nouă instanță User.

De exemplu:

const profile: Profile = new Profile();
profile.date_of_birth = '01/01/1984';

const user: User = new User();
user.email = '[email ';
user.name = 'John';
user.profile = profile;

await this.userRepository.save(user);

Acest lucru va păstra utilizatorul și profilul. În înregistrarea utilizatorului, o coloană profile_id, care indică cheia primară a profilului, este adăugată automat pentru tine.

Utilizator

Profil

https://github.com/typeorm/typeorm/blob/2e671386f486dab908c54a9488334dc54f82c735/src/decorator/options/RelationOptions.ts#L16