我想要的是每当创建新行程时, room
列应该填充 ${tripId}_${someRandomStringHere}
。因此,例如,我刚刚使用此主体创建了一个新行程:
新创建的 trip
具有 id
的 15
。因此,响应的 room
的值为 15_4gupvdo0ea408c25ia0qsbh
因为再次: ${tripId}_${someRandomStringHere}
。
每当我 POST
请求并创建行程时,这都会按 预期 工作。 但是 每当我查询创建的所有行程时,每个行程对象的 room
属性都会显示 null
!
Look at the /api/trips:
room
属性为 NULL 。所以到底是什么我不明白发生了什么。
我的 Trip Entity
代码是:
import { PrimaryGeneratedColumn, Column, CreateDateColumn,
UpdateDateColumn, Entity, Unique, ManyToOne, AfterInsert, JoinColumn, getConnection } from 'typeorm'
import { DriverEntity } from 'src/driver/driver.entity';
@Entity('trips')
export class TripEntity {
@PrimaryGeneratedColumn()
id: number
@Column()
destination: string
@Column('decimal')
destination_lat: number
@Column('decimal')
destination_long: number
@Column()
maxPassenger: number
@Column()
totalPassenger: number
@Column({ nullable: true })
room: string
@CreateDateColumn()
created_at: Date
@UpdateDateColumn()
updated_at: Date
// --------->HERE: The after insert
@AfterInsert()
async createSocketRoom(): Promise<void> {
const randomString = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
this.room = `${this.id}_${randomString}`
}
// Trip belongs to driver
// Adds driver_id to trips table
@ManyToOne(type => DriverEntity, driver => driver.trips)
@JoinColumn({ name: 'driver_id' })
driver: DriverEntity
}
我的 Trip Service Code
是:
async create(data: CreateTripDTO) {
const { driver_id } = data
const driver = await this.driverRepository.findOne({ where: { id: driver_id } })
const trip = await this.tripRepository.create(data)
trip.driver = driver
await this.tripRepository.save(trip)
return trip
}
我不认为我需要包含 Trip Controller
代码但无论如何..我不知道为什么会这样,因为我的用户实体带有 @BeforeUpdate 并且工作正常……
在阅读了很多类似的 github 问题之后,观看了 youtube 教程 [Hi Ben Awad! :D], 我找到了一些修复.. 通过使用订阅者
其实我不知道Listener/Subscriber有什么区别。也许我用错了。有人可以启发我吗?例如,实体监听器的 AfterSave 与实体订阅者的 AfterSave 的区别。何时/最佳情况下使用?类似的东西。无论如何回到 "fix..."
我创建了一个 Trip Subscriber
:
import { EventSubscriber, EntitySubscriberInterface, InsertEvent } from "typeorm";
import { TripEntity } from "src/trip/trip.entity";
@EventSubscriber()
export class TripSubsriber implements EntitySubscriberInterface<TripEntity> {
// Denotes that this subscriber only listens to Trip Entity
listenTo() {
return TripEntity
}
// Called after entity insertion
async afterInsert(event: InsertEvent<any>) {
console.log(`AFTER ENTITY INSERTED: `, event.entity);
const randomString = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
// query the trip with given event.entity
const trip = await event.manager.getRepository(TripEntity).findOne(event.entity.id)
// populate the room with desired format
trip.room = `${trip.id}_${randomString}`
// save it!
await event.manager.getRepository(TripEntity).save(trip)
}
}
起初它不起作用,但再次挖掘了几个小时后,我需要添加一个 subscriber
属性,其值为我的订户在 ormconfig.json
的路径值才能正常工作!例如: "subscribers": [
"src/subscriber/*.ts"
]
同样, Trip Subscriber
代码对我来说似乎是意大利面条,因为我已经有了 event.entity
对象,但我不知道如何更新它而无需使用 event.manager.getRepository()
。请有人可以为我修复此代码吗?正确的做法是什么?
我的问题是:
- 为什么每当我使用那个方法 method subscriber 时,它都不起作用。这不是正确的方法吗?为什么它在文档中?还是用于其他用例?
- 我真的必须使用订户才能实现吗?这么多步骤。
我来自 Rails。所以必须创建文件/订阅者才能做到这一点有点累人。与 ActiveRecord 的 after_save
回调不同,它非常容易..
附言。我是 nest-js 和 typeorm 的新手
原文由 Welp 发布,翻译遵循 CC BY-SA 4.0 许可协议
@AfterInsert
方法将在插入数据库完成后修改您的 JS 对象。这就是为什么您的代码不起作用的原因。你必须使用@BeforeInsert
装饰器。BeforeInsert
将在插入/保存到数据库之前修改您的 JS 实体/对象。