prisma-client-extensions icon indicating copy to clipboard operation
prisma-client-extensions copied to clipboard

Examples for Before/After Hooks on Create/Update/Delete, Soft Deletes, and Removing Methods

Open MichaelrMentele opened this issue 2 years ago • 1 comments

VERY excited for this feature. Thank you for the examples!

One area I'm confused about is adding a side-effect to a model CUD action.

This could be replacing the delete action with a custom delete action or making sure some log is always written on table creation. Is this possible?

Also in the docs it says extensions could be used for soft-deletes and for removing deletes entirely would love examples of these two usecases as well.

Also, does this work so that if you override a method on a model you can ensure that nested creates on other models will work as well? For example, if I want to make sure there is no delete method on a model and remove that operation how can I prevent a nested delete on all the other models?

// extend model to disallow deletes

db.someModel.delete <- should be undefined

db.someOtherRelatedModel.update({
    where: ...,
    data: { someModel: { delete: true } }, // shouldn't work
})

MichaelrMentele avatar Feb 23 '23 22:02 MichaelrMentele

// extension
export default function extendDealTradeIn(prisma: PrismaClient) {
  return prisma.$extends({
    model: {
      vehicle: {
        delete: undefined,
      },
    },
  })
}
// test
  describe('vehicle', () => {
    it('delete method is undefined', async () => {
      // The direct method is removed...
      expect(db.vehicle.delete).toBeUndefined()
    })

    it('nested deletes are undefined', async () => {
      // the indirect delete is NOT prevented...
      const vehicle = await fakeVehicle()
      const vehicleCount = await db.vehicle.count({ where: { id: vehicle.id } })
      expect(vehicleCount).toBe(1)
      await db.stage.update({
        where: {
          id: vehicle.stageId,
        },
        data: {
          vehicles: {
            delete: {
              id: vehicle.id,
            },
          },
        },
      })
      const newVehicleCount = await db.vehicle.count({
        where: { id: vehicle.id },
      })
      // without the extension, this SHOULD be 0
      // with the extension this SHOULD be 1 but either way
      // in both cases the new vehicle count is 0 meaning
      // the vehicle was deleted
      expect(newVehicleCount).toBe(1)
    })
  })

MichaelrMentele avatar Feb 23 '23 22:02 MichaelrMentele