Combine models in Prisma Schema - prisma

I have a Prisma Schema like below. That works fine for sure. But I have a lot of code duplication in RegionsPermissions and RolesPermissions. Is it possible to combine both in one single model?
model Roles {
id String #id #default(uuid())
name String
canCreateRegions RegionsPermissions #relation(fields: [createRegionsId], references: [id])
canCreateRoles RolesPermissions #relation(fields: [createRolesId], references: [id])
createRegionsId String #unique
createRolesId String #unique
}
model RegionsPermissions {
id String #id #default(uuid())
create Boolean
read Boolean
update Boolean
delete Boolean
role Roles?
}
model RolesPermissions {
id String #id #default(uuid())
create Boolean
read Boolean
update Boolean
delete Boolean
role Roles?
}

Related

Does Prisma create a new relationship collection when using MongoDB?

Looking at the Prisma docs and they show the example below. In this instance, if I'm using MongoDB and define my schema as per below, does Prisma create a collection for me called _CategoryToPost on my behalf to record the many to many relationships?
Or do I have to create my own collection to document this relationship?
model User {
id Int #id #default(autoincrement())
email String #unique
name String?
role Role #default(USER)
posts Post[]
profile Profile?
}
model Profile {
id Int #id #default(autoincrement())
bio String
user User #relation(fields: [userId], references: [id])
userId Int #unique
}
model Post {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
title String
published Boolean #default(false)
author User #relation(fields: [authorId], references: [id])
authorId Int
categories Category[] #relation(references: [id])
}
model Category {
id Int #id #default(autoincrement())
name String
posts Post[] #relation(references: [id])
}
enum Role {
USER
ADMIN
}
Link to docs
Prisma will create the necessary collections when you run the npx prisma db push command. You should not need to worry about the underlying structure beyond that.

Setting relationship between instances in Prisma

I am struggling with setting up Many-to-Many relationship in a graphQL resolver where the instances already exist (I'm only connecting them, not creating new instances, which many of the tutorials and docs show explicitily). Does anyone know of examples I could look at? In Sequelize, I would be using
fooInstance.setBar().
Here is my prisma schema:
id Int #id #default(autoincrement())
email String #unique
username String #unique
password String
points Int #default(0)
comments Comment[]
stations StationsFavoredByUsers[]
// trains Train[]
}
model Station {
id String #id
user StationsFavoredByUsers[]
}
model StationsFavoredByUsers {
user User #relation(fields:[userId], references: [id])
userId Int
station Station #relation(fields:[stationId], references: [id])
stationId String
##id([userId, stationId])
}```

Prisma - How to point two fields to same model?

I'm having trouble conceptualizing how to handle this issue. I've pored through the Prisma docs and other SO questions, but they all seem to be slightly different from this situation.
I have two models:
model User {
id Int #id #default(autoincrement())
firstName String? #map("first_name")
lastName String? #map("last_name")
email String #unique
password String
role UserRole #default(value: USER)
image String? #map("image")
createdAt DateTime #default(now()) #map("created_at")
updatedAt DateTime #updatedAt #map("updated_at")
friends Friend[]
##map("users")
}
model Friend {
id Int #id #default(autoincrement())
inviteSentOn DateTime #map("invite_sent_on") #db.Timestamptz(1)
inviteAcceptedOn DateTime #map("invite_accepted_on") #db.Timestamptz(1)
userId Int #map("user_id")
friendId Int #map("friend_id")
createdAt DateTime #default(now()) #map("created_at")
updatedAt DateTime #updatedAt #map("updated_at")
user User #relation(fields: [userId], references: [id])
// friend User? #relation(name: "FriendFriend", fields: [friendId], references: [id])
##map("friends")
}
I want to be able to set up the relationships on the Friend model to both point towards the User model, however I receive errors such as Error validating field 'friend' in model 'Friend': The relation field 'friend' on Model 'Friend' is missing an opposite relation field on the model 'User'.
I've tried adding the name property to the #relation field, but start receiving errors about ambiguous relations being detected.
How do I go about setting these relations up correctly?
You just need to provide name to disambiguate relation, like that:
model User {
id Int #id #default(autoincrement())
friend Friend?
friends Friend[] #relation(name: "friends")
}
model Friend {
id Int #id #default(autoincrement())
userId Int
friendId Int
user User #relation(fields: [userId], references: [id])
friend User #relation(fields: [friendId], references: [id], name: "friends")
}
And dont forget that both sides of relations need to have connections to the other.

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")
}

One-to-many and may-to-many relation between two prisma model

I am working on a side project and I came to an issue that I'm not sure how to solve. I have created two models, one for User and one for Project. The relation between them is many-to-many, as many users can have many projects, but i would also like to add a createdBy to the Project model, and this should be one-to-one as each project can only have one user who creates it. This is how my models are looking:
model User {
id String #id #default(cuid())
name String?
email String? #unique
emailVerified DateTime?
image String?
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
accounts Account[]
sessions Session[]
projects Project[]
Project Project[] #relation("userId")
}
model Project {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
name String
favourite Boolean #default(false)
archived Boolean #default(false)
users User[]
about String?
archivedAt String?
deletedAt String?
createdBy User #relation("userId", fields: [userId], references: [id])
userId String
}
The error that is getting from prisma migrate dev is
Step 1 Added the required column userId to the Project table without a default value. There are 2 rows in this table, it is not possible to execute this step.
Not sure what I am doing wrong as am pretty much a db modeling novice. Any help would be appreciated.
To achieve Many-to-Many with One-To-Many you need to set your schema.prisma file like:
model User {
id String #id #default(cuid())
name String?
email String? #unique
emailVerified DateTime?
image String?
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
projects Project[]
userProjects UserProjects[]
}
model Project {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
name String
favourite Boolean #default(false)
archived Boolean #default(false)
about String?
archivedAt String?
deletedAt String?
createdBy User #relation(fields: [user_id], references: [id])
user_id String
projectUsers UserProjects[]
}
model UserProjects {
project Project #relation(fields: [project_id], references: [id])
project_id Int
user User #relation(fields: [user_id], references: [id])
user_id String
##id([project_id, user_id])
}
It should migrate successfully.