how to create a flexible number of posts using prisma - prisma

This might not be possible but is there a way to create an flexible amount of posts in prisma. For example, I have a user and I would like them to create be able to create any amount of posts at once, so it would be one post or three posts. Is this possible using Prisma?
Here is the query I'm using:
const user = await prisma.user.update({
where: {
id: 9,
},
data: {
posts: {
// This is where I would like to make the amount of posts being created on the frontend flexible
createMany: {
data: [{ title: 'My first post' }, { title: 'My second post' }],
},
},
},
})

Here you go an example how to do that:
const { PrismaClient } = require('#prisma/client')
const prisma = new PrismaClient()
const saveData = async () => {
const user = await prisma.user.create({
data: {
name: 'John Doe',
posts: {
createMany: {
data: [
{
title: 'First Post',
},
],
}
}
},
include: {
posts: true
}
})
console.log(JSON.stringify(user, null, 2));
await prisma.user.update({
where: {
id: user.id
},
data: {
posts: {
createMany: {
data: [
{
title: 'Second Post',
},
{
title: 'Third Post',
}
],
}
}
}
})
console.log(JSON.stringify(await prisma.user.findMany({ include: {posts: true} }), null, 2));
}
saveData()
And here you go the result

Related

PrismaClientValidationError: Missing required argument in connectOrCreate

Problem:When I try and send/store data in my database I get this error. Specifically, I am trying to create/save a classroom with student names.
Tech Used:
Prisma/Postgres connected to AWS RDS and Next.js, deployed on Vercel, etc.
Error Message
PrismaClientValidationError: Argument data.classrooms.upsert.0.create.students.connectOrCreate.0.create.school.connect of type schoolWhereUniqueInput needs at least one argument.
Argument data.classrooms.upsert.0.update.students.upsert.0.create.school.connect of type schoolWhereUniqueInput needs at least one argument.
at Document.validate (/var/task/node_modules/#prisma/client/runtime/index.js:29501:20)
at serializationFn (/var/task/node_modules/#prisma/client/runtime/index.js:33060:19)
at runInChildSpan (/var/task/node_modules/#prisma/client/runtime/index.js:22550:12)
at PrismaClient._executeRequest (/var/task/node_modules/#prisma/client/runtime/index.js:33067:31)
at async PrismaClient._request (/var/task/node_modules/#prisma/client/runtime/index.js:32994:16)
at async profile (/var/task/.next/server/pages/api/user/profile.js:175:27)
at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils/node.js:366:9)
at async NextNodeServer.runApi (/var/task/node_modules/next/dist/server/next-server.js:481:9)
at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:735:37)
at async Router.execute (/var/task/node_modules/next/dist/server/router.js:247:36) {
clientVersion: '4.9.0'
}
DB Models with relationships: school (1 to many w/students); students (many to many with classrooms); teachers (one to many with students, many to many with classrooms)
Code/Prisma Query
export default async (req, res) => {
...
classroom.students.forEach((student) => {
const totalStudentPoints = student.rewardsRecieved.reduce(
(totalPoints, reward) => {
return totalPoints + reward.pointValue;
},
0
);
groups[student.group.name] += totalStudentPoints;
});
return { ...classroom, groupsTotalPoints: groups };
});
user.classrooms = newClassrooms;
res.json(user);
} else {
console.log("Could Not Find User");
res.status(401).json({
error: "Not authorized",
});
}
}
if (req.method === "PUT") {
const connectStudents = (shouldUpsert) => {
const students = req.body.students;
return students.map((student) => {
const UNSAFEHASH = md5(student.id);
const studentQuery: any = {
where: {
id: student.id,
},
create: {
id: student.id,
firstName: student.firstName,
lastName: student.lastName,
profilePicture: student.profilePicture,
userKey: UNSAFEHASH,
school: {
connect: {
id: req.body.schoolId,
},
},
group: {
connect: {
id: student.group.id,
},
},
},
};
if (shouldUpsert) {
studentQuery.update = {
firstName: student.firstName,
lastName: student.lastName,
profilePicture: student.profilePicture,
userKey: UNSAFEHASH,
group: {
connect: {
id: student.group.id,
},
},
};
}
return studentQuery;
});
};
try {
const user = await prisma.staff.update({
where: {
id: session.id,
},
data: {
firstName: req.body.firstName,
lastName: req.body.lastName,
classrooms: {
upsert: [
{
where: {
id: req.body.classId || "-1",
},
create: {
// id: req.body.classId,
name: req.body.className,
subject: req.body.classSubject,
students: {
connectOrCreate: connectStudents(false),
},
},
update: {
name: req.body.className,
subject: req.body.classSubject,
students: {
upsert: connectStudents(true),
},
},
},
],
},
},
});
Take a look at the PUT request and the prima.staff.update method more specifically. I was looking at the UPSERT I have there, but I can't figure out what's wrong.

Mongoose: $unshift with findOneAndUpdate is not working properly

I have this model:
const ProfileSchema = new Schema({
profileImageURLs: [
{
url: {
type: String,
},
current: {
type: Boolean,
},
date: {
type: Date,
default: Date.now,
},
},
],
});
And I have this function that updates the profileImageURLs field:
const updateProfileImageUrl = async (user_id) => {
const search_option = {
user: user_id,
};
const update_option = {
profileImageURLs: {
$unshift: {
url: `https://resources/profile_image`,
current: true,
},
},
};
const should_return_updated_profile = { new: true };
const updated_profile = await Profile.findOneAndUpdate(
search_option,
update_option,
should_return_updated_profile
);
console.log(
"🚀 ~ file: profileServices.js ~ line 1558 ~ updateProfileImageUrl ~ updated_profile",
updated_profile
);
};
The problem is the it is ignoring the values url and current in update_option and is only creating the _id and date fields:
profileImageURLs: [ { _id: 635ce632d633392b42c49094, date: 2022-10-29T08:37:06.012Z }]
And when I do a second update, instead of adding a new value to the beginning of the array, it creates a new array with the new values. So I have another array with a single object like that.
Any idea what's going on??
I used this instead and it works just fine:
const profile = await Profile.findOne(search_option);
profile.profileImageURLs.unshift({
url: profileImageURL,
current: true,
});
const updated_profile = await profile.save();

How to use Custom HTTP request and paginations, sort, search in Vue 2.x

I am an engineer who makes web systems in Tokyo.
I'm making a search system using Grid.js, but I faced a problem.
I don't know the solution because it's not in the documentation.
Since this system uses Vue 2.x, it uses axios.post with Custom HTTP Requset.
I was able to get the list, but I'm having trouble implementing sorting, pagination, and keyword search.
I want to send parameters by Post request.
Please tell me how to implement this.
The code is below
data() {
return {
columns: [
{name: 'user name', id: 'user_name'},
{name: 'email', id: 'email'},
],
page: {
enabled: true,
limit: 100,
server: {
body: (prev, page) => {
console.log(page) // OK, show page number 0,1,2...
return {
page: page
}
}
},
},
sort: {
},
search: {
server: {
// url: (prev, keyword) => `${prev}?q=${keyword}`
// what's this.
}
},
server: {
url: '/api/v2/users/list',
method: 'POST',
async data (opt) {
let response = await axios.post(opt.url)
return {
data: response.data.results.map(item => {
return {
username: item.username,
email: item.email,
}
}),
total: response.data.count,
}
}
},
};
OK.
Set POST payload this.
data() {
return {
columns: [
{name: 'user name', id: 'user_name'},
{name: 'email', id: 'email'},
],
page: {
enabled: true,
limit: 100,
server: {
body: (prev, page) => {
console.log(page) // OK, show page number 0,1,2...
return {
page: page
}
}
},
},
sort: {
},
search: {
server: {
// url: (prev, keyword) => `${prev}?q=${keyword}`
// what's this.
}
},
server: {
url: '/api/v2/users/list',
method: 'POST',
body: {},
async data (opt) {
let response = await axios.post(opt.url)
return {
data: response.data.results.map(item => {
return {
username: item.username,
email: item.email,
}
}),
total: response.data.count,
}
}
},
};

Merge or 'reference' and object into another through GraphQL?

Very new to graphQL (and MongoDB), and I am wondering how to reference an another object in graph QL.
I have two objects in two collections in MongoDB...
{
_id: 1,
companies: [
{
id: 1,
name: 'Google'
},
{
id: 2,
name: 'Apple'
}
]
}
{
_id: 2,
jobs: [
{
id: 1,
title: 'Designer'
},
{
id: 2,
name: 'Developer'
}
]
}
The Designer job is posted by google, and I want to include that in the returned object from GraphQL (I am using the 'id: 1' as a reference I guess? Presume ObjectID might be the way to go instead tho )
How would I go about that?
Ideally I want to return
{
"data": {
"job": {
"id": 1,
"title": "Designer",
"company": {
id: 1,
name: "Google"
}
}
}
}
But not sure how to go about it, I currently have...
resolvers.js
export const resolvers = {
Query: {
jobs: async (_parent, {}, context) => {
const jobs = await context.db
.collection('jobs')
.findOne()
return jobs.jobs
},
companies: async (_parent, {}, context) => {
const companies = await context.db
.collection('companies')
.findOne()
return companies.companies
},
job: async (_parent, { id }, context) => {
const job = await context.db.collection('jobs').findOne()
return job.jobs.find((job) => job.id === Number(id))
},
},
}
typeDefs.js
export const typeDefs = gql`
type Job {
_id: ID
id: Int
title: String
}
type Company {
_id: ID
id: Int
name: String
}
type Query {
jobs: [Job]
companies: [Company]
job(id: Int): Job
}
`
But not sure how to tie these in together? I am using Apollo / GraphQL / MongoDB / NextJS and essentially set up very close to this
Thanks in advance for any help or guidance!

Google Actions Smart Home on Lambda not working

I've been trying to get my Google Actions Smart Home (nodejs) working in AWS lambda. However it isn't working. Whenever I connect it on the Google Home app, I just get a message of "Couldn't update the setting...". I've already configured the API gateway correctly and set the Handler to "index.smarthome" as shown in the below image link. Why isn't it working, and how can I get my lambda google action smart home working?
Image Link
My firebase version is working though (modified from the washing machine example at https://codelabs.developers.google.com/codelabs/smarthome-washer/#2).
const functions = require('firebase-functions');
const {smarthome} = require('actions-on-google');
const app = smarthome();
app.onSync(body => {
return {
requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
payload: {
agentUserId: '123',
devices: [{
id: 'washer',
type: 'action.devices.types.WASHER',
traits: [
'action.devices.traits.OnOff',
'action.devices.traits.StartStop',
'action.devices.traits.RunCycle',
'action.devices.traits.Modes',
'action.devices.traits.Toggles',
],
name: {
defaultNames: ['My Washer'],
name: 'Washer',
nicknames: ['Washer']
},
deviceInfo: {
manufacturer: 'Acme Co',
model: 'acme-washer',
hwVersion: '1.0',
swVersion: '1.0.1'
},
attributes: {
pausable: true,
availableModes: [{
name: 'load',
name_values: [{
name_synonym: ['load'],
lang: 'en'
}],
settings: [{
setting_name: 'small',
setting_values: [{
setting_synonym: ['small'],
lang: 'en'
}]
}, {
setting_name: 'large',
setting_values: [{
setting_synonym: ['large'],
lang: 'en'
}]
}],
ordered: true
}],
availableToggles: [{
name: 'Turbo',
name_values: [{
name_synonym: ['turbo'],
lang: 'en'
}]
}]
}
}]
}
};
});
app.onExecute((body) => {
const {requestId} = body;
const payload = {
commands: [{
ids: [],
status: 'SUCCESS',
states: {
online: true,
},
}],
};
for (const input of body.inputs) {
for (const command of input.payload.commands) {
for (const device of command.devices) {
const deviceId = device.id;
payload.commands[0].ids.push(deviceId);
for (const execution of command.execution) {
const execCommand = execution.command;
const {params} = execution;
switch (execCommand) {
case 'action.devices.commands.OnOff':
payload.commands[0].states.on = params.on;
break;
case 'action.devices.commands.StartStop':
payload.commands[0].states.isRunning = params.start;
break;
case 'action.devices.commands.PauseUnpause':
payload.commands[0].states.isPaused = params.pause;
break;
case 'action.devices.commands.SetModes':
break;
case 'action.devices.commands.SetToggles':
break;
}
}
}
}
}
return {
requestId: requestId,
payload: payload,
};
});
exports.smarthome = functions.https.onRequest(app);
And here is the code that I used in my AWS lambda function. I referenced https://github.com/actions-on-google/actions-on-google-nodejs & creating dialogflow v2 project with serverless to make it lambda compatible. The main difference between the lambda and firebase versions is the "exports.smarthome" code.
const {smarthome} = require('actions-on-google');
const app = smarthome();
app.onSync(body => {
return {
requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
payload: {
agentUserId: '123',
devices: [{
id: 'washer',
type: 'action.devices.types.WASHER',
traits: [
'action.devices.traits.OnOff',
'action.devices.traits.StartStop',
'action.devices.traits.RunCycle',
'action.devices.traits.Modes',
'action.devices.traits.Toggles',
],
name: {
defaultNames: ['My Washer'],
name: 'Washer',
nicknames: ['Washer']
},
deviceInfo: {
manufacturer: 'Acme Co',
model: 'acme-washer',
hwVersion: '1.0',
swVersion: '1.0.1'
},
attributes: {
pausable: true,
availableModes: [{
name: 'load',
name_values: [{
name_synonym: ['load'],
lang: 'en'
}],
settings: [{
setting_name: 'small',
setting_values: [{
setting_synonym: ['small'],
lang: 'en'
}]
}, {
setting_name: 'large',
setting_values: [{
setting_synonym: ['large'],
lang: 'en'
}]
}],
ordered: true
}],
availableToggles: [{
name: 'Turbo',
name_values: [{
name_synonym: ['turbo'],
lang: 'en'
}]
}]
}
}]
}
};
});
app.onExecute((body) => {
const {requestId} = body;
const payload = {
commands: [{
ids: [],
status: 'SUCCESS',
states: {
online: true,
},
}],
};
for (const input of body.inputs) {
for (const command of input.payload.commands) {
for (const device of command.devices) {
const deviceId = device.id;
payload.commands[0].ids.push(deviceId);
for (const execution of command.execution) {
const execCommand = execution.command;
const {params} = execution;
switch (execCommand) {
case 'action.devices.commands.OnOff':
payload.commands[0].states.on = params.on;
break;
case 'action.devices.commands.StartStop':
payload.commands[0].states.isRunning = params.start;
break;
case 'action.devices.commands.PauseUnpause':
payload.commands[0].states.isPaused = params.pause;
break;
case 'action.devices.commands.SetModes':
break;
case 'action.devices.commands.SetToggles':
break;
}
}
}
}
}
return {
requestId: requestId,
payload: payload,
};
});
exports.smarthome = function(event, context, callback) {
app.handler(event, {})
.then((res) => {
if (res.status != 200) {
callback(null, {
"fulfillmentText": `I got status code: ${res.status}`
});
} else {
callback(null, res.body);
}
}).catch((e) => {
callback(null, {
"fulfillmentText": `There was an error\n${e}`
});
});
};
Check your AWS CloudWatch logs and see what happens when the lambda is called. You can print to stdout in your lambda and have it show up in these logs.
Along with your Cloudwatch logs, you could also have a look at your Stackdriver logs.