This gist is in response to a RedwoodJS Discord question from Andrew (HH):
How do I create a worker with many skills?
Andrew (HH)12/11/2020
export const createWorker = ({ input }) => {
return db.worker.create({
data: {
...input,
skills: {
// skillIds === [1,2,3]
connect: input.skillIds.map((skillId) => ({ id: skillId }))
}
}
})
}
I got the following error:
Unknown arg skills in data.skills for type WorkerUncheckedCreateInput.`
Andrew (HH)12/11/2020
I'm able to add skills after I've created the worker by using a separate db.worker.update but I wonder can I do it in the create function?
Given the Prisma schema:
datasource DS {
// optionally set multiple providers
// example: provider = ["sqlite", "postgresql"]
provider = "sqlite"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
binaryTargets = "native"
}
model Skill {
id Int @id @default(autoincrement())
name String @unique
workers Worker[]
}
model Worker {
id Int @id @default(autoincrement())
name String @unique
skills Skill[]
}
The following seeds will create and then connect Skills to new Workers:
/* eslint-disable no-console */
const { PrismaClient } = require('@prisma/client')
const dotenv = require('dotenv')
dotenv.config()
const db = new PrismaClient()
async function main() {
console.log('Create Skill')
const nunchuk = await db.skill.create({
data: { name: 'Nunchuk' },
})
const bow = await db.skill.create({
data: { name: 'Bow Hunting' },
})
const hacking = await db.skill.create({
data: { name: 'Computer Hacking' },
})
const allSkills = [{ id: nunchuk.id }, { id: bow.id }, { id: hacking.id }]
console.log('Create Worker')
const napolean = await db.worker.create({
data: { name: 'Napolean Dynamite', skills: { connect: allSkills } },
})
console.log(napolean)
const kip = await db.worker.create({
data: { name: 'Kip', skills: { connect: { id: hacking.id } } },
})
console.log(kip)
const napoleanWithSkills = await db.worker.findFirst({
where: { name: 'Napolean Dynamite' },
include: { skills: true },
})
console.log(napoleanWithSkills)
const kipWithSkills = await db.worker.findFirst({
where: { name: 'Kip' },
include: { skills: true },
})
console.log(kipWithSkills)
}
main()
.catch((e) => console.error(e))
.finally(async () => {
await db.$disconnect()
})
And the output of yarn rw db seed
is:
Seeding your database... [started]
Create Skill
Create Worker
{ id: 1, name: 'Napolean Dynamite' }
{ id: 2, name: 'Kip' }
{
id: 1,
name: 'Napolean Dynamite',
skills: [
{ id: 1, name: 'Nunchuk' },
{ id: 2, name: 'Bow Hunting' },
{ id: 3, name: 'Computer Hacking' }
]
}
{ id: 2, name: 'Kip', skills: [ { id: 3, name: 'Computer Hacking' } ] }
Seeding your database... [completed]
/* eslint-disable no-console */
const { PrismaClient } = require('@prisma/client')
const dotenv = require('dotenv')
dotenv.config()
const db = new PrismaClient()
async function main() {
const nunchuk = { name: 'Nunchuk' }
const bow = { name: 'Bow Hunting' }
const hacking = { name: 'Computer Hacking' }
console.log('Create Worker')
const napolean = await db.worker.create({
data: {
name: 'Napolean Dynamite',
skills: { create: [nunchuk, bow] },
},
})
console.log(napolean)
const kip = await db.worker.create({
data: {
name: 'Kip',
skills: { create: [hacking] },
},
})
console.log(kip)
const napoleanWithSkills = await db.worker.findFirst({
where: { name: 'Napolean Dynamite' },
include: { skills: true },
})
console.log(napoleanWithSkills)
const kipWithSkills = await db.worker.findFirst({
where: { name: 'Kip' },
include: { skills: true },
})
console.log(kipWithSkills)
}
main()
.catch((e) => console.error(e))
.finally(async () => {
await db.$disconnect()
})
then seeding will:
Seeding your database... [started]
Create Worker
{ id: 1, name: 'Napolean Dynamite' }
{ id: 2, name: 'Kip' }
{
id: 1,
name: 'Napolean Dynamite',
skills: [ { id: 1, name: 'Nunchuk' }, { id: 2, name: 'Bow Hunting' } ]
}
{ id: 2, name: 'Kip', skills: [ { id: 3, name: 'Computer Hacking' } ] }
Seeding your database... [completed]
✨ Done in 1.68s.
But, when creating, you need to name sure what you are nesting/creating will be unique.