Issue regarding 1-m relation - prisma

The current relation i have is that One user can only have 1 sublevel. And sublevel can have more users.
But when i try to create a sublevel ( without any reference at this time ) Lets say , i want to have a new sublevel where users can not be assigned just yet. It does not work.
Current Scheme:
model User {
id String #id #default(auto()) #map("_id") #db.ObjectId
email String #unique
password String
firstName String
lastName String
address String
postalCode String
city String
country String
email_verified Boolean
subLevelId String?
sub SubLevel? #relation(fields: [subLevelId], references: [id], onDelete: Cascade)
}
model SubLevel {
id String #id #default(auto()) #map("_id") #db.ObjectId
sublevelName String
sublevelCost Float
users User[]
}
The error i get is:
3 export const createSubLevel = ({ input }) => { api | → 14 return db.subLevel.create({ api | data: { api |
sublevelName: 'Cryptek-Standard', api | sublevelCost: 0,
api | + user: { api | + create?:
UserCreateWithoutSubLevelInput |
UserUncheckedCreateWithoutSubLevelInput, api | +
connectOrCreate?: UserCreateOrConnectWithoutSubLevelInput, api |
connect?: UserWhereUniqueInput api | + }, api | ? id?: String api | } api | }) api | api | Argument
user for data.user is missing. api | api | Note: Lines with + are
required, lines with ? are optional.
Is it not possible in prisma to do this ? I searched the docu but i can not seem to find the answer for it.

Changed into a 1-1 relationship

Related

name: 'LinkAccountError', [next-auth][error][adapter_error_linkAccount]

I am making a sign up page with 3 providers (Twitter, Facebook and Instagram) using next-auth and prisma with mongoDB. The issue appears when I try to sign up with any of the providers. I think the prisma schema is the problem. Here is the error that I receive:
Invalid `p.account.create()` invocation in
C:\...\node_modules\#next-auth\prisma-adapter\dist\index.js:19:42
16 },
17 updateUser: ({ id, ...data }) => p.user.update({ where: { id }, data }),
18 deleteUser: (id) => p.user.delete({ where: { id } }),
→ 19 linkAccount: (data) => p.account.create({
data: {
provider: 'instagram',
type: 'oauth',
providerAccountId: '62921xxxxxx98535',
access_token: 'IGQVJYdU...',
user_id: 178xxxx,
~~~~~~~
userId: '63e2538xxxx'
}
})
Unknown arg `user_id` in data.user_id for type AccountUncheckedCreateInput. Did you mean `userId`? Available args:
type AccountUncheckedCreateInput {
id?: String
userId: String
type: String
provider: String
providerAccountId: String
}
I have red all the documentations about, chatGPT also didn't help much. The prisma schema looks like this:
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String #id #default(auto()) #map("_id") #db.ObjectId
name String?
email String? #unique
emailVerified DateTime? #map("email_verified")
image String?
accounts Account[]
sessions Session[]
##map("users")
}
model Account {
id String #id #default(auto()) #map("_id") #db.ObjectId
userId String #db.ObjectId
type String
provider String
providerAccountId String #map("provider_account_id")
refresh_token String? #db.String
access_token String? #db.String
expires_at Int?
token_type String?
scope String?
id_token String? #db.String
session_state String?
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
##unique([provider, providerAccountId])
##map("accounts")
}
model Session {
id String #id #default(auto()) #map("_id") #db.ObjectId
sessionToken String #unique #map("session_token")
userId String #db.ObjectId
expires DateTime
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
##map("sessions")
}
model VerificationToken {
identifier String #id #default(auto()) #map("_id") #db.ObjectId
token String #unique
expires DateTime
##unique([identifier, token])
##map("verificationtokens")
}
You are passing user_id parameter while creating an account, but there is no field named user_id in the Account model in your schema file.
If you need to pass user_id while creating an account then you need to define it in the Account model as well.

Unable to pass multiple filters in Prisma where clause

I am using Prisma, MongoDB and NextAuth in a Next js project (Typescript). I'm trying to pass multiple filters in the where clause, but it returns a null array.
In the app there are 2 pages, one is called My Feed where anyone (even if not logged in) can see everyone's published posts. Second page is called My Drafts, where logged in users can view their unpublished posts, and choose to publish or delete them.
Basically, when a user creates a new post, it has a property - published, which is false by default. I am trying to show these unpublished posts, in the my drafts page of a logged in user.
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
const session = await getSession({ req });
if (!session) {
res.statusCode = 403;
return { props: { drafts: [] } };
}
const drafts = await prisma.post.findMany({
where: {
published: false,
author : {email: session.user?.email}
},
include: {
author: {
select: { name: true },
},
},
});
return {
props: { drafts },
};
};
If I remove the author from the where clause, it returns all unpublished posts from all users. If I remove the published:false or keep both - published and email then I'm getting null array, although session is defined.
Here is my prisma schema : -
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model Post {
id String #id #default(auto()) #map("_id") #db.ObjectId
title String
content String?
published Boolean #default(false)
author User? #relation(fields: [authorId], references: [id])
authorId String?
}
model Account {
id String #id #default(auto()) #map("_id") #db.ObjectId
userId String #map("user_id")
type String
provider String
providerAccountId String #map("provider_account_id")
refresh_token String? #db.String
access_token String? #db.String
expires_at Int?
token_type String?
scope String?
id_token String? #db.String
session_state String?
oauth_token_secret String?
oauth_token String?
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
##unique([provider, providerAccountId])
}
model Session {
id String #id #default(auto()) #map("_id") #db.ObjectId
sessionToken String #unique #map("session_token")
userId String #map("user_id")
expires DateTime
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String #id #default(auto()) #map("_id") #db.ObjectId
name String?
email String? #unique
emailVerified DateTime?
image String?
posts Post[]
accounts Account[]
sessions Session[]
}
model VerificationToken {
id String #id #default(auto()) #map("_id") #db.ObjectId
identifier String
token String #unique
expires DateTime
##unique([identifier, token])
}

How Do I Resolve This Prisma relationship schema error

model Match {
id String #id #unique #default(cuid())
name String
description String
player1 User #relation( fields: [player1Id], references: [id])
player1Id String
player2 User #relation( fields: [player2Id], references: [id])
player2Id String
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
leagueId String
}
model User {
id String #id #unique #default(uuid())
email String #unique
password String
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
matches Match[]
}
Getting following error
Error: Schema parsing
error: Error validating model "Match": Ambiguous relation detected. The fields `player1` and `player2` in model `Match` both refer to `User`. Please provide different relation names for them by adding `#relation(<name>).
--> schema.prisma:85
|
84 | description String
85 | player1 User #relation(fields: [player1Id], references: [id])
86 | player1Id String
|
want to keep track of all of the matches the user plays, each match has two players (Users)

How to select a custom User model property?

I added a company property to the User model in my prisma.schema file (The rest of the prisma.schema file is still similar to the one in the documentation: https://next-auth.js.org/adapters/prisma)
model User {
id String #id #default(cuid())
name String?
email String? #unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
company Company?
}
model Company {
id Int #id #default(autoincrement())
companyName String #unique
gender String
firstName String
lastName String
street String
houseNumber Int
postcode Int
city String
country String
countryCode String
callNumber Int
emailAddress String
website String?
socials Json?
companyUser User #relation(fields: [companyUserId], references: [id])
companyUserId String #unique
}
The whole authentification process is working fine even after the change but when I try to select a User from the database it only returns a certain portion of the User namely the id, name, email, emailVerified and image property.
How can I change this behaviour?
const user = await prisma.user.findUnique({
where: {
id: ...
}
})
For sure I could only create the Company model without connecting it to the User model and maybe adding the User's id to it to have an implicit connection, but that's undermining the whole purpose...
you're looking for nested reads, if you want to include the whole company model you should use include with the name of the relation, note that this will return all the fields for that specific relation:
const user = await prisma.user.findUnique({
where: {
id: ...
},
include: {
company: true,
},
})
if you want to return specific relation fields with the whole user you should use select inside include:
const user = await prisma.user.findUnique({
where: {
id: ...
},
include: {
company: {
select : {
firstName: true,
},
},
},
})

Prisma: Model with three unique index fields referencing optional fields

I got a question regarding unique indexes with optional values.
I have a schema like this:
model Thread {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
body String
user User #relation(fields: [userId], references: [id])
userId Int
likes Like[] #relation("ThreadsOnLikes")
}
model Like {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
user User #relation(fields: [userId], references: [id])
userId Int
thread Thread? #relation("ThreadsOnLikes", fields: [threadId], references: [id])
threadId Int?
comment Comment? #relation("CommentsOnLikes", fields: [commentId], references: [id])
commentId Int?
##unique([userId, threadId, commentId])
}
And inside a resolver I want to for example delete a like from a user for a specific threadId like so:
await db.thread.update({
where: { id: input.id },
data: {
likes: {
delete: {
userId_threadId_commentId: { userId: session.userId, threadId: input.id },
},
}
}
})
But when I try to execute that mutation, prisma throws the following error:
Argument commentId for data.likes.delete.userId_threadId_commentId.commentId is missing.
When I add it to the delete argument with , commentId: null it states this error:
Argument commentId: Got invalid value null on prisma.updateOneThread. Provided null, expected Int.
Although inside the database the comment_id field is actually null . Is this a bug or how is this fixable?
From the docs:
All fields that make up the unique constraint must be mandatory fields. The following model is not valid because id could be null:
model User {
firstname Int
lastname Int
id Int?
##unique([firstname, lastname, id])
}
The reason for this behavior is that all connectors consider null values to be distinct, which means that two rows that look identical are considered unique:
firstname | lastname | id
-----------+----------+------
John | Smith | null
John | Smith | null
I am not sure why Prisma is unable to validate schema beforehand in "compile time", maybe it is a bug, so I suggest you to maybe create an issue on Github?