javascript - 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;
}
解决方案
该save
方法在之前加载了关系INSERT
,因此无法执行save
for ,生成的settings
查询将首先尝试然后,如您所说 - 在事务中无法选择未提交的记录,这就是为什么它不不工作。SELECT
user
INSERT
settings
可以做什么?两种选择:
- 保存嵌套的实体
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);
});
- 插入用户,然后插入
settings
和profile
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
});
推荐阅读
- swiftui - Swiftui iOS14.5 键盘隐藏了 DatePicker 但非常适合 TextField
- java - 寻找有关 java.lang.System.load 的说明
- reactjs - 如何使用 CDN 将 JS 脚本和 HTML 传递到 Shopify 网站
- r - R中先前制作的组中随机处理的平均分布
- python - 合并三个 keras 模型,取决于一个输出
- c# - 如何按其他对象的属性对对象列表进行排序
- python - 单元测试中的请求对象
- arrays - SQLite JSON_EXTRACT 数组中 1 个对象的所有值
- python - SumTree 实现无法正常工作
- javascript - 比较数组中的图像