can i use "AND" to where in connectOrCreate for prisma? - node.js

i want to make new holding. there are two cases.
there are no product, no account.
there are one product, account.
so i use connectOrCreate!. I want to find accountNum with userId and accountNumber
so i use AND in where. but there are error.
Unknown arg AND in data.accountNum.connectOrCreate.where.AND for type AccountNumberWhereUniqueInput. Did you mean id? Available args
const holding = await client.holding.create({
data: {
holdingNum,
accountNum: {
connectOrCreate: {
where: { AND: [{ userId: loggedInUser.id }, { accountNumber }] },
create: {
accountNumber,
user: {
connect: {
id: loggedInUser.id,
},
},
org: {
connect: {
orgCode,
},
},
},
},
},
product: {
connectOrCreate: {
where: {
prodCode,
},
create: {
prodCode,
prodName,
},
},
},
},
});
model AccountNumber {
id Int #id #default(autoincrement())
org Organization #relation(fields: [orgId], references: [id])
orgId Int
user User #relation(fields: [userId], references: [id])
userId Int
accountNum String
holdings Holding[]
}
model Holding {
id Int #id #default(autoincrement())
accountNum AccountNumber #relation(fields: [accountNumId], references: [id])
accountNumId Int
product Product #relation(fields: [productId], references: [id])
productId Int
holdingNum Int
evalAmt Int?
}
model Product {
id Int #id #default(autoincrement())
prodName String
prodCode String #unique
posts Post[]
holdings Holding[]
proposes Propose[]
}

I think you do not need the AND :
accountNum: {
connectOrCreate: {
where: { userId: loggedInUser.id , accountNumber },
...
}

Related

Delete a single document from nested document array by its id

I have this model for a user, the user can also be a driver and the driver have an array of cars. I want to delete a specific car from all the cars of drivers, but my query deletes all the cars.
This is the schema:
const UserSchema = new mongoose.Schema({
name: {
type: String,
},
driverData: {
ExperienceLevel: {
type: String,
},
rides: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "ride.model",
},
],
cars: [
{
id: {
type: mongoose.Schema.Types.ObjectId,
},
licensePlateNumber: {
type: String,
},
},
],
},
});
Code I am using to pull a car by id.
user = await User.findByIdAndUpdate(
{ _id: userId },
{ driverData: { cars: { $pull: { id: carId } } } }
);
Only a single car object and a single car id is left after making this query, all other data is removed. How to only remove only a single car.
Your syntax is incorrect. Try this:
user = await User.findByIdAndUpdate( { _id: userId }, { $pull: { driverData: { cars: { $elemMatch: { id: carId } } } } );

Get custom attribute depend on pivot table in nest js with prisma ORM

What is the efficient way to map Prisma query results depending on the logged-on user and pivot table?
Here is my schema
model User {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
email String #unique
password String
firstName String
lastName String?
favouriteMovies FavouriteMovie[]
##map("users")
}
model Movie {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
title String
year Int
rating Float
category String
posterUrl String
favouriteMovies FavouriteMovie[]
##map("movies")
}
model FavouriteMovie {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
user User #relation(fields: [userId], references: [id], onDelete: Cascade)
userId Int
movie Movie #relation(fields: [movieId], references: [id], onDelete: Cascade)
movieId Int
##map("favourite_movies")
}
Which is the best way to retrieve isFavourite attribute with the Movie query result?
Here's the query which would return the movie details of the logged-in user.
import { PrismaClient } from '#prisma/client';
const prisma = new PrismaClient();
async function main() {
// Creating User
const user = await prisma.user.create({
data: {
email: 'sundarani#prisma.io',
firstName: 'Nurul',
lastName: 'Sundarani',
password: 'test',
},
});
// Creating Movie
const movie = await prisma.movie.create({
data: {
title: 'The Matrix',
category: 'Action',
posterUrl: 'https://i.imgur.com/dZQMx5q.jpg',
rating: 5,
year: 1999,
},
});
// Adding movie to user
const favouriteMovie = await prisma.favouriteMovie.create({
data: {
movieId: 1,
userId: 1,
},
});
// Getting Movie details of favourite movie of user
const getMovieDetailsFromUserId = await prisma.favouriteMovie.findMany({
where: {
userId: 1, // Logged In User
},
include: {
movie: true,
},
});
console.log(getMovieDetailsFromUserId);
}
main()
.catch((e) => {
throw e;
})
.finally(async () => {
await prisma.$disconnect();
});
Response:
[
{
id: 1,
createdAt: 2022-06-14T11:31:49.415Z,
updatedAt: 2022-06-14T11:31:49.417Z,
userId: 1,
movieId: 1,
movie: {
id: 1,
createdAt: 2022-06-14T11:30:10.747Z,
updatedAt: 2022-06-14T11:30:10.747Z,
title: 'The Matrix',
year: 1999,
rating: 5,
category: 'Action',
posterUrl: 'https://i.imgur.com/dZQMx5q.jpg'
}
}
]
Reference: Include.

NestJS-Prisma How to create record with relational fields?

i'm a begginer on NestJS and Prisma.
I'm trying to create an User, my table has relational Fields with table Addresses.
To create an user, i need first add a register into adresses table, to use adress_id on my user table.
I'm getting this error:
This is my code
Service:
async create(createUserDto: CreateUserDto) {
const hash = crypto.SHA256(createUserDto.password);
const passwordHash = (hash.toString(crypto.enc.Hex).toUpperCase());
const createCategory = await this.client.user.create({
data: {
name: createUserDto.name,
email: createUserDto.email,
age: createUserDto.age,
password: passwordHash,
roleId: createUserDto.roleId,
address: {
create: [
{
street: createUserDto.address.street,
number: createUserDto.address.number,
complement: createUserDto.address.complement,
neighborhood: createUserDto.address.neighborhood,
cityId: createUserDto.address.cityId,
stateId: createUserDto.address.stateId,
zipcode: createUserDto.address.zipcode
},
],
},
},
})
}
DTO:
export class CreateUserDto {
readonly id: number
readonly name :string
readonly age :any
readonly email :any
readonly password :any
readonly roleId :any
readonly addressId: number
readonly address: {
street: string,
number: number,
complement: string,
neighborhood: string,
cityId: number,
stateId: number,
zipcode: string
}
}
Schema.prisma
model user {
id Int #id #default(autoincrement())
name String
age Int
email String #unique
password String
roleId Int
role role #relation(fields: [roleId], references: [id])
addressId Int
address addresses #relation(fields: [addressId], references: [id])
}
model addresses {
id Int #id #default(autoincrement())
street String
number String
complement String
neighborhood String
cityId Int
city cities #relation(fields: [cityId], references: [id])
stateId Int
state state #relation(fields: [stateId], references: [id])
zipcode String
user user[]
}
What am i doing wrong?
Thanks!
Your address.create syntax is wrong. User-Address is a one-to-many relation, so one user can only have one address. So address.create should be passed a single address object, not an array.
This should work fine
const createCategory = await this.client.user.create({
data: {
name: createUserDto.name,
email: createUserDto.email,
age: createUserDto.age,
password: passwordHash,
roleId: createUserDto.roleId,
address: {
create: {
street: createUserDto.address.street,
number: createUserDto.address.number,
complement: createUserDto.address.complement,
neighborhood: createUserDto.address.neighborhood,
cityId: createUserDto.address.cityId,
stateId: createUserDto.address.stateId,
zipcode: createUserDto.address.zipcode
},
},
},
})

Automatically add UUID relation on prisma create

I have a User, UserProfile and Post model in my Postgres database. The User and UserProfile depend on each other. I am trying to create a User that automatically creates a UserProfile with it, but I can't seem to find out how to automatically assume the User's ID for the UserProfile relation, I am using UUID for the User model.
Schema Models
model User {
id String #id #default(uuid())
createdAt DateTime #default(now())
username String #unique #db.VarChar(20)
emailEncrypted String #unique
emailIv String #unique
password String
isMod Boolean #default(false)
isAdmin Boolean #default(false)
emailConfirmed Boolean #default(false)
profile UserProfile?
}
model UserProfile {
user User #relation(fields: [id], references: [id])
id String #unique
posts Post[]
comments Comment[]
}
model Post {
id String #id #default(uuid())
createdAt DateTime #default(now())
title String #db.VarChar(300)
caption String #db.VarChar(1000)
upvotes Int #default(0)
downvotes Int #default(0)
comments Comment[]
author UserProfile #relation(fields: [authorId], references: [id])
authorId String
}
Query
const user = await prisma.user.create({
data: {
username,
emailEncrypted: encrypted,
emailIv: iv,
password: hashedPassword,
profile: {
create: {}, // create a UserProfile that assumes the created user's UUID as a relation
},
},
select: {
id: true,
},
});
As you can see, I have tried to use create: {} in order to assume the user's UUID, but it fails to create an actual UserProfile, just a User, which of course breaks the system.
I ran this as well. In order to include profile data after creating the user I did the following tweak.
const user = await prisma.user.create({
data: {
username: "username",
emailEncrypted: "encrypted",
emailIv: "iv",
password: "hashedPassword",
profile: {
create: {},
},
},
select: {
id: true,
createdAt: true,
emailConfirmed: true,
emailIv: true,
emailEncrypted: true,
isAdmin: true,
isMod: true,
password: true,
profile: true,
username: true,
},
});
This outputs,
No issue it worked fine.
Still wondering what the issue you faced was.
Can you paste the error log ?.
This is the correct way of adding relations in Prisma. You use create to add a relation and the UUID will automatically be added to that record. You do not need to do anything else. I tried the following and works fine for me:

How to connect multiple m-n relationship records

I have a schema that looks like this:
model School {
id Int #id #default(autoincrement())
name String
teachers Teacher[]
students Student[]
}
model Teacher {
id Int #id #default(autoincrement())
firstName String
lastName String
schools School[]
students Student[]
}
model Student {
id Int #id #default(autoincrement())
firstName String
lastName String
teacherId Int
teacher Teacher #relation(fields: [teacherId], references: [id])
schoolId Int
school School #relation(fields: [schoolId], references: [id])
}
I want to create in a single call a school, with teacher and student. This is my attempt:
prisma.school.create({
data: {
name: "Best",
teachers: {
create: {
id: 2,
firstName: "Charles",
lastName: "Wise",
students: {
create: {
firstName: "Pauline",
lastName: "Jenkins",
school: {
connect: {
id: -1 // How to reference a school that is being created?
}
}
}
}
}
}
}
});
Unfortunately I have no clue how to pass a school's id when creating a student.
I know that I can do it in two calls by first creating a school with a teacher and then creating a student with that just created school and teacher:
const school = await prisma.school.create({
data: {
name: "Best",
teachers: {
create: {
id: 2,
firstName: "Charles",
lastName: "Wise",
}
}
},
include: {
teachers: true,
}
});
await prisma.student.create({
data: {
firstName: "Pauline",
lastName: "Jenkins",
school: {
connect: {
id: school.id
}
},
teacher: {
connect: {
id: school.teachers[0].id
}
}
}
});
But that looks kind of weird and error prone.
Is there a way to rewrite it to a single call?
You can try this code snippet to either connect to if a record exists or create on the go when it is not there.
prisma.teachers.create({
data: {
id: 2,
firstName: 'Charles',
lastName: 'Wise',
students: {
create: {
firstName: 'Pauline',
lastName: 'Jenkins',
},
},
school: {
connectOrCreate: {
where: {
name: 'best',
},
create: {
name: 'best',
},
},
},
},
});

Resources