Soft delete

After the fix, we can now actually implement this functionality.

To have soft deletion, let's go back to the RegistryDates and add the field deletedAt to it. This will, likewise, add the field to all entities that have a registryDates. The only entity that does not have it is OrderItem, so please add this field there manually. With this, entities can now be soft-deleted, as the time of this deletion will be registered.

@DeleteDateColumn()
deletedAt: Date;

Then, we should generate and run the migration add-deleted-at.

Now, return to the User entity and, in its relation with Order, indicate that the orders should also be soft-deleted with cascade. With this, the orders related to this user will also be hidden from searches, except if stated otherwise.

cascade: ['soft-remove', 'recover'],

We don't need to worry about doing the same with Order and its items and payment because they already have cascade: true defined.

Let's now create a DTO to represent whether a removal should be a hard or soft deletion. Create then the file common/dto/remove.dto.

export class RemoveDto {
  @IsOptional()
  @IsBoolean()  
  readonly soft: boolean;
}

Remember to import our own @IsBoolean() decorator instead of the default one.

Finally, to actually use this feature, let's go back to the UsersController and make the remove() route have its query parameters represented by the DTO that we just created.

remove(@Param() { id }: IdDto, @Query() { soft }: RemoveDto) {
  return this.usersService.remove(id, soft);
}

In the UsersService, the remove() method should then perform the deletion according to the value of soft.

async remove(id: number, soft: boolean) {
  const user = await this.findOne(id);
  return soft
    ? this.usersRepository.softRemove(user)
    : this.usersRepository.remove(user);
}

We could also have a route just for soft deletion, it would be an alternative.

However, in order to have the soft delete work with cascade, all the corresponding relations need to be fetched as well for them to also be soft-deleted. Due to this, let's add all the necessary relations in the findOne() method.

relations: {
  orders: {
    items: true,
    payment: true,
  },
},

With this, we can continue to store some user accounts after their deletion and only hide them, if desired. In the next section, we'll learn how to recover them.

Last updated