首页 > 解决方案 > TypeORM - 创建具有关系的用户

问题描述

当新用户注册时,我想创建一些要自动设置的关系。目前,我正在这样做:

const user = await User.create({
  email,
  password: hashedPassword,
}).save();

const settings = await Settings.create({
  userId: user.id,
}).save();

const settings = await Profile.create({
  userId: user.id,
}).save();

根据我的阅读,事务是处理依赖操作的最佳方式,但 PG 在保存之前不会创建用户 ID。

这是我能想到的最好的交易:

const user = await User.create({
  email,
  password: hashedPassword,
}).save();

const settings = await Settings.create({
  userId: user.id,
});

const profile = await Profile.create({
  userId: user.id,
});

await getConnection().transaction(async (transactionalEntityManager) => {
  await transactionalEntityManager.save(settings);
  await transactionalEntityManager.save(profile);
});

但是,仍然存在用户保存的可能性,但关系没有。

有没有更好(或更简单的方法)来处理这个问题?

用户实体.ts

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

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;

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

  @Column()
  password!: string;

  @OneToOne(() => Settings, (settings) => settings.user)
  settings: Settings;

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

settings.entity.ts

@Entity()
export class Settings {
  @PrimaryColumn()
  userId: number;

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

profile.entity.ts

@Entity()
export class Profile {
  @PrimaryColumn()
  userId: number;

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

标签: javascriptpostgresqltypeorm

解决方案


save方法在之前加载了关系INSERT,因此无法执行savefor ,生成的settings查询将首先尝试然后,如您所说 - 在事务中无法选择未提交的记录,这就是为什么它不不工作。SELECTuserINSERT settings

可以做什么?两种选择:

  1. 保存嵌套的实体
const user = await getConnection()
.transaction((transactionalEntityManager) => {
   const userObj = User.create({
      email,
      password: hashedPassword,
   })

   userObj.profile = Profile.create({});
   userObj.settings = Settings.create({});

   return transactionalEntityManager.save(User, userObj);
});
  1. 插入用户,然后插入settingsprofile
const userInsertResult = await getConnection()
.transaction(async (transactionalEntityManager) => {

const userInsertResult = await transactionalEntityManager
                .createQueryBuilder(User,'user')
                .insert()
                .into(User)
                .values({
                   email,
                   password: hashedPassword
                }).execute();

const settingsInsertResult = await transactionalEntityManager
                .createQueryBuilder(Settings,'settings')
                .insert()
                .into(Settings)
                .values({
                   userId: userInsertResult.raw.id
                }).execute();

const profileInsertResult = await transactionalEntityManager
                .createQueryBuilder(Profile,'profile')
                .insert()
                .into(Profile)
                .values({
                   userId: userInsertResult.raw.id
                }).execute();

 return userInsertResult
});

推荐阅读