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!
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 toonDelete: SET_NULL
by default. This means that deleting a node results in setting the other side of the relation tonull
.
You can read more about cascading deletes in Prisma in the documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With