Relasi Many-to-Many di Prisma
Prisma adalah sebuah pustaka JavaScript yang sangat powerful. Beberapa database seperti PostgreSQL, mysql, dan sqlite, sudah kucoba tanpa masalah dengan menggunakan pustaka ini. Dari generate tabel-tabel sampai melakukan query data.
Dari sekian banyak pustaka yang kugunakan, Prisma ini bisa dibilang masih awam. Sulitnya mencari tutorial menjadi alasan utama.
Berikut di sini, aku akan mencoba menjelaskan bagaimana menggunakan relasi many-to-many di Prisma. Sebagai contoh, aku membuat 2 buah tabel Post
dan Tag
untuk menyimpan artikel yang memiliki beberapa tanda.
Tabel Post
:
model Post {
id Int @id @default(autoincrement())
title String
content String?
tags Tag[]
createdAt DateTime @default(now())
}
dan tabel Tag
:
model Tag {
id Int @id @default(autoincrement())
name String @unique
slug String @unique
posts Post[]
}
Untuk mencari id
dari Tag:
export const getTagIds = async (tagcsv: string) => {
const ids = [];
if (tagcsv) {
const tagNames = tagcsv.split(',');
const tags = tagNames.map(async (tagName) => {
const name = tagName.trim().toLowerCase();
const slug = slugify(name); // dari slugify
let tag = await db.tag.findFirst({
where: { slug: slug }
});
if (!tag) {
tag = await db.tag.create({
data: { name, slug }
});
}
return tag;
});
for (const tag of tags) {
ids.push({
id: (await tag)?.id
});
}
}
return ids;
}
Untuk isi dari variabel tagcvs
bisa seperti ini:
const tagcsv = 'merah, kuning, hijau'; // dari form input di web
Untuk melakukan penyimpanan baru pada sebuah artikel yang disimpan di tabel Post
:
const ids = await getTagIds(tagcsv);
const post = await db.post.create({
data: {
title: 'Lorem Ipsum',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
tags: {
connect: [...ids]
}
}
});
Untuk proses update berbeda dengan penyimpanan baru:
const ids = await getTagIds(tagcsv);
const post = await db.post.update({
where: { id: 1 },
data: {
title: 'Lorem Ipsum 2',
content: 'Nunc turpis magna, cursus at placerat tempus, aliquam eget lorem.',
tags: {
set: [...ids]
}
}
});
Untuk proses seeding
sendiri pun berbeda:
const tags = ['merah', 'kuning', 'hijau'];
for (let i = 0; i < 20; i++) {
const words = faker.random.words(5).split(' '); // dari @faker-js/faker
const title = words.map((word) => {
return word[0].toUpperCase() + word.substring(1);
}).join(" ");
const content = faker.lorem.paragraphs(3, '\n\n');
await prisma.post.create({
data: {
title,
content,
tags: {
connectOrCreate: tags.map((name) => {
return {
where: { slug: name },
create: {
name,
slug: name
}
}
})
}
}
});
}
Cara ini aku gunakan untuk melakukan proses create dan update untuk relasi many-to-many di Prisma. Entah kenapa berbeda-beda caranya supaya berjalan dengan baik, mungkin ada bagian dari dokumentasi yang terlewatkan.