0
votes

I have an entity Audit Like below in Nestjs app with typeorm for mongodb:

@Entity()
export class Audit {

  @Column()
  createdBy: string;

  @BeforeInsert()
  setAudit() {
    this.createdBy = ???
  }
}

@Entity()
export class Post extends Audit {

  @Column()
  title: string;

  ...
}

My other entities extend Audit and in my application i'm using jwt to authenticate users.

The problem is that when i want to save an entity i don't know how to set createdBy with @BeforeInsert hook...

I know we have user in request but i don't know what is the correct way of bringing user into setAudit method?

1

1 Answers

2
votes

You can't access the request directly from inside a TypeORM entity, as they are in separate contexts. You could, instead, fill the createdBy field through a service.

@Injectable()
class DataService {
// ...

   async create({ request, user }): Promise<any> {
    await this.repository.create({...request.body, createdBy: user.id });
   }

// ...
}

Another solution would be creating a common service that can work for every entity, and inside that service you could fill the createdBy property.

/*
 * DataService
 ? Service to be able to fetch any kind of TypeORM entity from the controllers
 ? or another services.
*/
@Injectable()
export class DataService {
    
    /*
     * _.getRepository
     ? Method to get a repository by having only the type of an entity.
     * @param type The type of the entity
     * @returns a repository of the specified entity.
    */
    private getRepository<T>(type: new () => T) {
        return getRepository(type)
    }
    
    /*
     * _.save
     ? A method to save an entity regarding its entity type.
     * @param type the type of the entity
     * @param model the model to save. It should have an ID.
     * @param user the user creating this entity
     * @returns a DeepPartial object representing the edited or created object.
    */
    public save<T extends Audit>(type: new () => T, model: DeepPartial<T>, user: User): Promise<DeepPartial<T> & T> {
        const repository: Repository<T> = this.getRepository(type);
        return repository.save({...model, createdBy: user.id});
    }

   
}

Then, you will be able to do something like this...

// ... 

@Post('create')
@UseInterceptor(FillUser)
public async create(@Body() body:any, @Req() request:any) {
  const { user } = request.session.user // <--- Just for example. 
  return await this.service.create(Post, body, user)
}

// ...