Combine multiple releations into single array prisma - prisma

I'm starting with primsa for the first time and I was wondering if there is an easy way of combining a relation.
E.g.
model Person {
id String #id #default(cuid())
name String
gender String
mother Person? #relation("Mother", fields: [motherId], references: [id], onDelete: NoAction, onUpdate: NoAction)
motherId String?
father Person? #relation("Father", fields: [fatherId], references: [id], onDelete: NoAction, onUpdate: NoAction)
fatherId String?
images HerringGullImage[]
childeren1 Person [] #relation("Mother")
childeren2 Person [] #relation("Father")
}
So now you have childeren from the mother and childeren for the father. I was wondering if you can combine these in prisma, or if I have to combine these after in code

Related

Both two Prisma schema have foreign key of each other's ID

model Users {
id Int #id #default(autoincrement())
business_id Int? #db.Int
Businesses Businesses? #relation(fields: [business_id], references: [id], onUpdate: Cascade, onDelete: Cascade)
name String #db.VarChar(255)
surname String #db.VarChar(255)
email String #unique(map: "email") #db.VarChar(255)
password String #db.VarChar(255)
}
model Businesses {
id Int #id #default(autoincrement())
name String #db.VarChar(255)
owner_id Int #db.Int
Users Users #relation(fields: [owner_id], references: [id], onUpdate: Cascade, onDelete: Cascade)
phone String #db.VarChar(255)
}
So the logic is like this that in the Model User the value of business id is opsional and in the Business's model the owner_id the ID is mandatory.
In the User's table I am getting this error:
Error parsing attribute "#relation": The relation fields `Users` on Model `Businesses` and `Businesses` on Model `Users` both provide the `fields` argument in the #relation attribute. You have to provide it only on one of the two fields.
And in the Business's model this error:
Error parsing attribute "#relation": The relation fields `Users` on Model `Businesses` and `Businesses` on Model `Users` both provide the `references` argument in the #relation attribute. You have to provide it only on one of the two fields.
Relationship Between User -> Business: many to one ( many users can be part of one business)
Relationship Between Business -> User : one to one (only one user can be the owner of one business)
Given the assumptions/relationships in your question
One business can have many users, each user can belong to only one business (one to many relationship, called "business2user" in the schema below)
One user can own one business, a business is owned by one user. (one to one relationship, called "business2owner" in the schema below)
a prisma.schema could look like this:
model User {
id Int #id #default(autoincrement())
business_id Int? #db.Int
business Business? #relation(fields: [business_id], references: [id], name: "business2user", onUpdate: Cascade, onDelete: Cascade)
name String #db.VarChar(255)
surname String #db.VarChar(255)
email String #unique(map: "email") #db.VarChar(255)
password String #db.VarChar(255)
ownedBusiness Business? #relation(name: "business2owner")
}
model Business {
id Int #id #default(autoincrement())
name String #db.VarChar(255)
owner_id Int #unique #db.Int
owner User #relation(fields: [owner_id], references: [id], name: "business2owner", onUpdate: Cascade, onDelete: Cascade)
users User[] #relation(name: "business2user")
phone String #db.VarChar(255)
}
I took the liberty to rename Users to User and Businesses to Business to improve interpretability.

Prisma update query only allowing an update by the ID field and not anything else

const response = await prisma.teamMember.update({
where: {
teamId,
userId: memberToEditId,
},
data: {
role,
},
});
Argument where of type TeamMemberWhereUniqueInput needs exactly one argument, but you provided teamId and userId. Please choose one. Available args:
type TeamMemberWhereUniqueInput {
id?: String
}
Unknown arg `teamId` in where.teamId for type TeamMemberWhereUniqueInput. Did you mean `id`? Available args:
type TeamMemberWhereUniqueInput {
id?: String
}
Unknown arg `userId` in where.userId for type TeamMemberWhereUniqueInput. Did you mean `id`? Available args:
type TeamMemberWhereUniqueInput {
id?: String
}
Hey guys. I'm trying to update a specific document based off of a specific value(s) in my table, but it only seems to let me use the primary key for the table? My schema looks like:
model TeamMember {
id String #id #default(cuid())
teamId String
userId String
role Role #default(MEMBER)
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
team Team #relation(fields: [teamId], references: [id], onDelete: Cascade)
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
}
model Team {
id String #id #default(cuid())
name String
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
TeamMember TeamMember[]
}
model User {
id String #id #default(cuid())
name String?
email String? #unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
TeamMember TeamMember[]
theme Theme #default(LIGHT)
}
To fix this, temporarliy I can make a separate findFirst query, and use the returned row to get the ID of the row which i want to update. This is fine, however I know it can be done without doing this, and it is a little ugly having two queries when one can work just fine.
Any help would be greatly appreciated.
Prisma needs to uniquely identify a single record which needs to be updated, due to which the whereUnique constraint is enforced.
For now, you can use updateMany as a workaround for this, this unique constraint is not enforced for updateMany

prisma nested writes throw unknown args

I have the shorten schema like that:
model PATIENT {
patient_id Int #id #default(autoincrement())
patient_name String
patient_identity_card BigInt #unique
password String
wallet_id Int?
birthday DateTime
address String
status_id Int
gender String #default("Nam")
phone String #default("0935438280")
current_treatment_place_id Int
avatar_url String?
treatment_place TREATMENT_PLACE #relation(fields: [current_treatment_place_id], references: [place_id])
status PATIENT_STATUS #relation(fields: [status_id], references: [status_id])
card CART?
patient_passive_contact PATIENT_CONTACT[] #relation("ActiveContact_referredToPatient")
patient_active_contact PATIENT_CONTACT[] #relation("PassiveContact_referredToPatient")
BE_MANAGED_HISTORY BE_MANAGED_HISTORY[]
}
model BE_MANAGED_HISTORY {
place_id Int
patient_id Int
time DateTime
status_id Int
status PATIENT_STATUS #relation(fields: [status_id], references: [status_id])
patient PATIENT #relation(fields: [patient_id], references: [patient_id])
place TREATMENT_PLACE #relation(fields: [place_id], references: [place_id])
change_type_id Int
change_type CHANGE_MANAGED_HISTORY_TYPE #relation(fields: [change_type_id], references: [type_id])
##id([place_id, patient_id, time])
}
I want to create a BE_MANAGED_HISTORY record and through it create a PATIENT record with needed information. The nested writes below:
const res = await prisma.BE_MANAGED_HISTORY.create({
data: {
place_id: treatmentPlaceId,
time: new Date(startDate),
status_id: patientStatus,
change_type_id: 1,
patient: {
create: {
patient_name: patientName,
gender,
birthday: new Date(birthday),
patient_identity_card: identity,
password: hashedPassword,
phone,
address,
status_id: patientStatus,
current_treatment_place_id: treatmentPlaceId,
avatar_url: avatarUrl,
}
}
},
})
But prisma throws an error:
Unknown arg patient in data.patient for type BE_MANAGED_HISTORYUncheckedCreateInput. Did you mean patient_id?
Argument patient_id for data.patient_id is missing.
So can I create an beManagedHistory and create an patient inside nested writes?
We have to create a PATIENT record first, and nested in it creating a BE_MANAGED_HISTORY record.

Prisma One-to-one relation issue

I have just recently started using prisma and I ran into an issue with relations. I have a user model and an address model.
model User {
id Int #id #unique #default(autoincrement())
username String
}
model Address {
id Int #id #unique #default(autoincrement())
street String
}
I need to add 2 addresses to the user: invoicing address and delivery address. In the address I don't need a user reference.
I thought this would work without issues by adding this to the user model:
invoiceAddress Address? #relation(name: "iAddress", fields: [iAddressId], references: [id])
deliveryAddress Address? #relation(name: "dAddress", fields: [dAddressId], references: [id])
iAddressId Int?
dAddressId Int?
But when saving the schema two user fields are added to the address model... which I don't need and now I have issues because they reference the same user model so I have to also name them and add scalar field...
Am I missing something??? This should be a basic use case imo.
This is a requirement from Prisma's end that relation fields should exist on both sides of the model, you cannot define relation field on only one model.
The following schema model should solve the issue for you:
model User {
id Int #id #unique #default(autoincrement())
username String
invoiceAddress Address? #relation(name: "iAddress", fields: [iAddressId], references: [id])
deliveryAddress Address? #relation(name: "dAddress", fields: [dAddressId], references: [id])
iAddressId Int?
dAddressId Int?
}
model Address {
id Int #id #unique #default(autoincrement())
street String
UserInvoice User[] #relation(name: "iAddress")
UserDelivery User[] #relation(name: "dAddress")
}
Please note that relation fields do not exist on database so UserInvoice and UserDelivery columns would not exist on Address table. Similarly invoiceAddress and deliveryAddress columns would not exist on User table.

Prisma schema one-to-many relations from multiple tables to one

I want to acomplish such schema, where user could have some images and recipes could have some images.
I came up with solution, but it throws this error for author and recipe rows in image model. My solution is to use type column as diferentiator between Recipe and User types.
Error parsing attribute "#relation": The given constraint name images_parentId_fkey has to be unique in the following namespace: on model Image for primary key, indexes, unique constraints and foreign keys. Please provide a different name using the map argument.
My solution:
model User {
id String #id #unique #default(dbgenerated("gen_random_uuid()")) #db.Uuid
images Image[] #relation("UserImages")
Recipe Recipe[] #relation("RecipeAuthor")
##map("users")
}
model Recipe {
id String #id #unique #default(dbgenerated("gen_random_uuid()")) #db.Uuid
authorId String #db.Uuid
author User #relation("RecipeAuthor", fields: [authorId], references: [id])
images Image[] #relation("RecipeImages")
##map("recipes")
}
model Image {
id String #id #unique #default(dbgenerated("gen_random_uuid()")) #db.Uuid
type String
parentId String #db.Uuid
author User #relation("UserImages", fields: [parentId], references: [id])
recipe Recipe #relation("RecipeImages", fields: [parentId], references: [id])
##map("images")
}
Only other solution I came up with is to create multiple tables for images, something like user_images and recipe_images, but i dont really like that and I might need even more tables like this in future, so I would rather find better way. Thanks in advance for any help :)
Instead of using parentId for both in UserImages and ReceipeImages relation. You can separate them out and have something like parentUserId and parentReceipeId.
The following solution could potentially work:
model User {
id String #id #unique #default(dbgenerated("gen_random_uuid()")) #db.Uuid
images Image[] #relation("UserImages")
Recipe Recipe[] #relation("RecipeAuthor")
##map("users")
}
model Recipe {
id String #id #unique #default(dbgenerated("gen_random_uuid()")) #db.Uuid
authorId String #db.Uuid
author User #relation("RecipeAuthor", fields: [authorId], references: [id])
images Image[] #relation("RecipeImages")
##map("recipes")
}
model Image {
id String #id #unique #default(dbgenerated("gen_random_uuid()")) #db.Uuid
type String
parentUserId String? #db.Uuid
parentReceipeId String? #db.Uuid
author User? #relation("UserImages", fields: [parentUserId], references: [id])
recipe Recipe? #relation("RecipeImages", fields: [parentReceipeId], references: [id])
##map("images")
}