From 3b9ec278cadb11f3da5ac968718a0b8e8d43d6c0 Mon Sep 17 00:00:00 2001 From: Michael Schwobe Date: Fri, 13 Oct 2023 12:01:09 -0500 Subject: [PATCH] Fixed `P2002` error with merging tags --- app/models/tag.server.ts | 22 +++++++++++++++++++--- app/routes/tags.$tagId.merge.tsx | 16 +++++----------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/app/models/tag.server.ts b/app/models/tag.server.ts index 79e594b..447e065 100644 --- a/app/models/tag.server.ts +++ b/app/models/tag.server.ts @@ -134,12 +134,28 @@ export async function deleteTagByName({ export async function mergeTag({ sourceTagId, targetTagId, + userId, }: { sourceTagId: Tag["id"]; targetTagId: Tag["id"]; + userId: User["id"]; }) { - return prisma.tagOnBookmark.updateMany({ - where: { tagId: sourceTagId }, - data: { tagId: targetTagId }, + const [sourceRelations, targetRelations] = await Promise.all([ + prisma.tagOnBookmark.findMany({ where: { tagId: sourceTagId } }), + prisma.tagOnBookmark.findMany({ where: { tagId: targetTagId } }), + ]); + const sourceBookmarkIds = sourceRelations.map((el) => el.bookmarkId); + const targetBookmarkIds = targetRelations.map((el) => el.bookmarkId); + const uniqueBookmarkIds = sourceBookmarkIds.filter( + (bookmarkId) => !targetBookmarkIds.includes(bookmarkId), + ); + const createBookmarkRelations = uniqueBookmarkIds.map((bookmarkId) => + prisma.tagOnBookmark.create({ + data: { tagId: targetTagId, bookmarkId }, + }), + ); + const deleteSourceTag = prisma.tag.deleteMany({ + where: { id: sourceTagId, userId }, }); + return prisma.$transaction([...createBookmarkRelations, deleteSourceTag]); } diff --git a/app/routes/tags.$tagId.merge.tsx b/app/routes/tags.$tagId.merge.tsx index e1e13f5..9925342 100644 --- a/app/routes/tags.$tagId.merge.tsx +++ b/app/routes/tags.$tagId.merge.tsx @@ -27,13 +27,7 @@ import { Icon } from "~/components/ui/icon"; import { Input } from "~/components/ui/input"; import { LinkButton } from "~/components/ui/link-button"; import { SelectItem, SimpleSelect } from "~/components/ui/select"; -import { - deleteTag, - getTag, - getTagByName, - getTags, - mergeTag, -} from "~/models/tag.server"; +import { getTag, getTagByName, getTags, mergeTag } from "~/models/tag.server"; import { requireUserId } from "~/utils/auth.server"; import { formatMetaTitle, @@ -80,16 +74,16 @@ export const action = async ({ params, request }: ActionFunctionArgs) => { const targetTag = await getTagByName({ name: submission.value.name }); invariantResponse(targetTag, "Target Tag Not Found", { status: 404 }); - const { count } = await mergeTag({ + const mergeTagResults = await mergeTag({ sourceTagId: sourceTag.id, targetTagId: targetTag.id, + userId, }); - await deleteTag({ id: sourceTag.id, userId }); return redirectWithToast(`/tags/${targetTag.id}`, { type: "success", - title: "Tags merged:", - description: `${count} relations updated`, + title: "Tag merged:", + description: `${mergeTagResults.length - 1} relation(s) updated`, }); };