prisma-client-rust
prisma-client-rust copied to clipboard
Creation of many-to-many relationship when inserting a new record
Hello, I am new to the Rust language itself. I am a beginner in the Rust language itself. I am currently learning and developing an application in TAURI.
https://prisma.brendonovich.dev/writing-data/create#create I have run into a bit of a problem and am stumped. The documentation above explains how to create a relationship, but in this example, if there are pre-existing posts, you can specify the ID of the post to be associated with when creating a comment.
However, if I have a "bookmark" and a "tags" table, for example, and they are in a many-to-many relationship with each other, how can I insert both IDs in the intermediate table when inserting a new bookmark?
The following is the current situation
model Bookmark {
id Int @id @default(autoincrement())
type String
content String
update_at DateTime @updatedAt
register_at DateTime @default(now())
Tags BookmarkTag[]
}
model Tag {
id Int @id @default(autoincrement())
name String @unique
icon Bytes?
icon_type String?
update_at DateTime @updatedAt
register_at DateTime @default(now())
TagStructure TagStructure[]
Bookmarks BookmarkTag[]
@@index([name])
}
model BookmarkTag {
bookmark_id Int
tag_id Int
bookmark Bookmark @relation(fields: [bookmark_id], references: [id], onDelete: Cascade)
tag Tag @relation(fields: [tag_id], references: [id], onDelete: Cascade)
@@id([bookmark_id, tag_id])
}
According to the type of prisma.rs generated, this is how it is written, but "BookmarkIdTagIdEquals()" does not know the ID of the record in the "bookmark" table that is newly inserted.
let result = state.storage.bookmark().create(
data_json.rtype, data_json.content, vec![
bookmark::tags::connect(vec![bookmark_tag::UniqueWhereParam::BookmarkIdTagIdEquals(5 /* don't know */, 2)])
]
).exec().await.map_err(|e| e.to_string())?;
Is there any better way to write prepared? Thank you very much.
Two things:
- Right now you can only make records for 1 model at a time, so first make your bookmark and second make your relation record. You can't
connect
in this case since there's noBookmarkTag
record that already exists to connect to. Creating nested relations is being tracked in #44 - Don't use
UniqueWhereParam
, instead usebookmark_tag::bookmark_id_tag_id(...)
Thank you for your response. I edited the code as advised and as a result I was able to build the relationship, but still had problems.
Below is the current prisma schema file.
model Bookmark {
id Int @id @default(autoincrement())
type String
url String? @unique
domain String?
title String?
description String?
icon Bytes?
icon_type String?
thumbnail Bytes?
thumbnail_type String?
content String?
update_at DateTime @updatedAt
register_at DateTime @default(now())
Tags BookmarkTag[]
@@index([url, type])
}
model Tag {
id Int @id @default(autoincrement())
name String @unique
icon Bytes?
icon_type String?
update_at DateTime @updatedAt
register_at DateTime @default(now())
TagStructure TagStructure[]
Bookmarks BookmarkTag[]
@@index([name])
}
model BookmarkTag {
bookmark_id Int
tag_id Int
bookmark Bookmark @relation(fields: [bookmark_id], references: [id], onDelete: Cascade)
tag Tag @relation(fields: [tag_id], references: [id], onDelete: Cascade)
@@id([bookmark_id, tag_id])
}
I initially attempted to set up a relationship using the following procedure, but while the code runs fine, nothing is actually inserted into the "BookmartTag" intermediate table.
pub struct Create {
pub tags: Vec<i32>, pub domain: Option<String>,
pub rtype: String, pub content: Option<String>,
pub title: Option<String>, pub url: Option<String>,
pub description: Option<String>, pub icon: Option<Vec<u8>>,
pub icon_type: Option<String>, pub thumbnail: Option<Vec<u8>>,
pub thumbnail_type: Option<String>
}
let parse_data: structs::bookmark::Create = data.create.unwrap();
let result = state.storage.bookmark().create(
parse_data.rtype, vec![
bookmark::title::set( parse_data.title ),
bookmark::description::set( parse_data.description ),
bookmark::url::set( parse_data.url ),
bookmark::icon::set( parse_data.icon ),
bookmark::icon_type::set( parse_data.icon_type ),
bookmark::thumbnail::set( parse_data.thumbnail ),
bookmark::thumbnail_type::set( parse_data.thumbnail_type ),
bookmark::domain::set( parse_data.domain ),
bookmark::content::set( parse_data.content )
]
).exec().await.map_err(|e| e.to_string())?;
let _updated = state.storage.bookmark().update(bookmark::id::equals( result.id ), vec![
bookmark::tags::set( parse_data.tags.iter().map(|&id| {
bookmark_tag::bookmark_id_tag_id(result.id, id)
}).collect())
]).with(bookmark::tags::fetch(vec![])).exec().await.map_err(|e| e.to_string())?;*/
We then tried to insert the data directly into the intermediate table as follows with success. This method is currently used.
for id in parse_data.tags.clone() {
state.storage.bookmark_tag().create(
bookmark::id::equals( result.id ), tag::id::equals(id), vec![]
).exec().await.map_err(|e| e.to_string())?;
}
Is this a bug? Or am I doing something wrong?