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:
Related
I am trying to register a user with an admin right on my mongodb admin user collection.
This is my admin model:
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
const adminUserSchema = new Schema({
userType: {
type: String,
},
email: {
type: String,
unique: true
},
password: {
type: String,
},
},
{
timestamps: true
}
);
export const adminUser = mongoose.model('adminUser', adminUserSchema);
Below is how I entered the admin collection:
{
userType
"adminUser"
email
"admin#mail.com"
password
"Password"
}
I got an error that the data cant be entered as it contains error.
The screenshort of the error:
Below is how I entered the admin collection:
{
userType
"adminUser"
email
"admin#mail.com"
password
"Password"
}
I got an error that the data cant be entered as it contains error.
The screenshort of the error:
What am I doing wrong?
Seeing your background filter, you need to separate values into key:value pair like JSON
{
userType: "adminUser"
email: "admin#mail.com"
password: "Password"
}
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.
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
},
},
},
})
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 },
...
}
I have a pretty good understanding of mongdoDB with mongoose, but this one aspect of it has been confusing me for a while now. I have a user.js model with a username, password, etc (all the basic user stuff). This data is added when a user registers for an account. But each user also has more data linked to it that IS NOT created or added at the time of registering.
This is my model:
// User Schema
const UserSchema = new Schema({
// PERSONAL USER INFO
username: {
type: String,
index: true
},
email: {
type: String
},
password: {
type: String
},
// INSTAGRAM ACCOUNT INFORMATION
ig_username: {
type: String
},
ig_password: {
type: String
},
story_price: {
type: Number
},
fullpost_price: {
type: Number
},
halfpost_price: {
type: Number
},
leads: [{
title: { type: String }
}]
});
// EXPORTS
const User = module.exports = mongoose.model('user', UserSchema);
All the field except "leads" are created at the time of registering. But I want to fill the Leads field using another form. I've tried the .update(), .save(), $set, $push, and all kinds of methods, but I cannot get it to work.
Most solutions that I have found use var user = new User({...}) to create a new user and then use .save() after adding the additional data. But this seems wrong since the user has already been created and I am just trying to add data to an additional field.
I think I'm just glossing over something basic, but if there is a way to do this I would be glad to hear it. Thanks!
I would create a sub-schema for leads
// Create a sub-schema for leads
const leadsSubSchema = new Schema({
title: {
type: String,
},
});
// Create a schema for user
const UserSchema = new Schema({
username: {
type: String,
index: true
},
// ...
leads: [leadsSubSchema]
});
// EXPORTS
const User = module.exports = mongoose.model('user', UserSchema);
Then for the update
User.update({
_id: user_id,
}, {
$push: {
leads: lead_to_add,
},
});