Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cascade delete related nodes using GraphQL and Prisma

I'm trying to figure out cascade deletion in GraphQL.

I'm attempting to delete a node of type Question, but type QuestionVote has a required relation to Question. I'm looking for a way to delete a Question and all its votes at once.

Mutation for deleting a Question:

type Mutation {
  deleteQuestion(where: QuestionWhereUniqueInput!): Question!
}

And its resolver (I'm using Prisma):

function deleteQuestion(parent, args, context, info) {
  const userId = getUserId(context)  
  return context.db.mutation.deleteQuestion(
      {
        where: {id: args.id}
      },
      info,
  )
}

How can I modify that mutation to also delete related QuestionVote nodes? Or should I add a separate mutation that deletes one or multiple instances of QuestionVote?

In case it's important, here are the mutations that create Question and QuestionVote:

function createQuestion(parent, args, context, info) {
    const userId = getUserId(context)
    return context.db.mutation.createQuestion(
        {
            data: {
              content: args.content,
              postedBy: { connect: { id: userId } },
            },
        },
        info,
    )
}

async function voteOnQuestion(parent, args, context, info) {
  const userId = getUserId(context)

  const questionExists = await context.db.exists.QuestionVote({
    user: { id: userId },
    question: { id: args.questionId },
  })
  if (questionExists) {
    throw new Error(`Already voted for question: ${args.questionId}`)
  }

  return context.db.mutation.createQuestionVote(
    {
      data: {
        user: { connect: { id: userId } },
        question: { connect: { id: args.questionId } },
      },
    },
    info,
  )
}

Thanks!

like image 453
Sam Hollon Avatar asked Oct 19 '25 10:10

Sam Hollon


1 Answers

You can set up cascade deletion by modifying your datamodel.

Given your question, I assume your datamodel looks somewhat like this:

type Question {
  id: ID! @unique
  votes: [QuestionVote!]! @relation(name: "QuestionVotes")
  text: String!
}

type QuestionVote {
  id: ID! @unique
  question: Question @relation(name: "QuestionVotes")
  isUpvote: Boolean!
}

Then you have to add the onCascade: DELETE field to the @relation directive like so:

type Question {
  id: ID! @unique
  votes: [QuestionVote!]! @relation(name: "QuestionVotes" onDelete: CASCADE)
  text: String!
}

type QuestionVote {
  id: ID! @unique
  question: Question @relation(name: "QuestionVotes")
  isUpvote: Boolean!
}

Now, every time a Question node is deleted, all related QuestionVote nodes are also deleted.

Note: If omitting onDelete, the value is automatically set to onDelete: SET_NULL by default. This means that deleting a node results in setting the other side of the relation to null.

You can read more about cascading deletes in Prisma in the documentation.

like image 94
marktani Avatar answered Oct 21 '25 14:10

marktani



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!