Does Prisma create a new relationship collection when using MongoDB? - 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.

Related

Prisma, without #relation?

model Post{
//...
place Place[] #relation(fields: [placeId], references: [id])
placeId Int
}
model Place{
//...
post Post #relation(fields: [postId], references: [id])
postId Int
}
when I do this,
I got this error
error: Error parsing attribute "#relation": The relation field place on Model Post must not specify the fields or references argument in the #relation attribute. You must only specif
y it on the opposite field post on model Place.
how to fix this??
and I don`t understand difference between
just simple post Post (without #relation)
and
post Post #relation(...)
A relation is used to show a connection between two entities or models in the Prisma schema. To fix your issue, you would do something like
model Post{
id Int #id #default(autoincrement())
place Place[]
}
model Place{
id Int #id #default(autoincrement())
post Post #relation(fields: [postId], references: [id])
postId Int
}
To learn more about relations, please do take a look at the docs
For an implicit many-to-many relation, you can do
model Post{
id Int #id #default(autoincrement())
place Place[]
}
model Place{
id Int #id #default(autoincrement())
post Post[]
postId Int
}

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.

Error validating: This line is not a valid field or attribute definition

I wonder why my model (the Like-model) does not work as I expect it to.
Maybe someone can explain?
model User {
id Int #id #default(autoincrement())
likes Like[]
}
model Like {
fromUser User #relation(fields: [fromUserId] references: [id])
fromUserId Int
toUser User #relation(fields: [toUserId] references: [id])
toUserId Int
##id([fromUserId, toUserId])
}
The error reads: Error validating: This line is not a valid field or attribute definition.
It points at fromUser User #relation(fields: [fromUserId] references: [id]) and toUser User #relation(fields: [toUserId] references: [id]).
You would need to model your relations in the following manner:
model User {
id Int #id #default(autoincrement())
likedUsers Like[] #relation("likedUsers")
usersWhoLiked Like[] #relation("usersWhoLiked")
}
model Like {
id Int #id #default(autoincrement())
likedUser User? #relation("likedUsers", fields: [likedUserId], references: [id])
likedUserId Int?
userWhoLiked User? #relation("usersWhoLiked", fields: [userWhoLikedId], references: [id])
userWhoLikedId Int?
}
Whenever you have more than 1 relation to a model you need to provide a relation name to disambiguate the relation.
Also you need to store which users you have liked and who liked the current user. So you would need two relations for this.
Missing commas.
The solution might look like this:
model User {
id Int #id #default(autoincrement())
likes Like[]
}
model Like {
fromUser User #relation(fields: [fromUserId], references: [id])
fromUserId Int
toUser User #relation(fields: [toUserId], references: [id])
toUserId Int
##id([fromUserId, toUserId])
}

How to filter for related objects in Prisma?

How can query relationships in Prisma? I have the following schema:
model User {
id Int #id #default(autoincrement())
name String?
profile Profile
}
model Profile {
id Int #id #default(autoincrement())
user User #relation(fields: [userId], references: [id])
userId Int
}
How can I query a Profile for a specific User?
Found the answer myself:
prisma.user.findUnique({ where: { id: 42 }}).profile()