Hi everyone, Entry level dev with an easy one :sl...
# prisma-client
r
Hi everyone, Entry level dev with an easy one 🙂 I'm missing something about how
?
this works with a relation, or in general. I have a model
Issue
with a field
assignedTo
that takes a relation
User?
as an optional field.
Copy code
model Issue {
  id          Int      @id @default(autoincrement())
  createdAt   DateTime @default(now())
  title       String
  description String
  createdBy   User     @relation(name: "createdByUser", fields: [createdById], references: [id])
  createdById Int

  assignedTo   User? @relation(name: "assignedTo", fields: [assignedToId], references: [id])
  assignedToId Int?
}
However, I can't seem to find a way to write a query to
create
or
update
that doesn't demand an
Int
at
assignedTo
without the query failing. For example, the query below won't work unless there is an
Int
at
input.isssue.assignedTo.id
.
Copy code
const newIssue = await db.issue.create({
      data: {
        title: input.issue.title,
        description: input.issue.description,
        createdBy: {
          connect: {
            id: ctx.session.userId,
          },
        },
        assignedTo: {
          connect: {
            id: Number(input.issue.assignedTo.id),
          },
        },
      },
    })
I tried passing in
null
and
undefined
directly but both are rejected by the schema. Or should there be separate create and update queries for optional fields?
Copy code
if(input.issue.assignedTo.id) { createIssueWithAssignedUser()}
  else {createIssue()}
m
Seperate queries is one workaround. Can you try like this (I don't know if it works, didn't try):
Copy code
const newIssue = await db.issue.create({
      data: {
        title: input.issue.title,
        description: input.issue.description,
        createdBy: {
          connect: {
            id: ctx.session.userId,
          },
        },
        assignedTo: {
          set:  input.number.issue.assignedTo.id ? [{id: Number(input.number.issue.assignedTo.id}] : []
        },
      },
    })
r
Thanks Maciek! At the moment, this field is not set up as a List. That was my plan but I wanted to keep it simple and add that later. So, your suggestion won't work. However, neither does:
Copy code
assignedTo: {
  connect: { id : assignedTo ?Number(assignedTo.id) : undefined 
     },
  },
So. I'll continue with the workaround. I think there is a basic pattern for writing queries and handling form data that I am missing. But that's why I am doing this project. To figure this stuff out :)
m
I have used
set
not
connect
. Anyway try like this:
Copy code
const newIssue = await db.issue.create({
      data: {
        title: input.issue.title,
        description: input.issue.description,
        createdBy: {
          connect: {
            id: ctx.session.userId,
          },
        },
        (assignedTo.id && 
          assignedTo: {
            connect: {
              id: Number(assignedTo.id)
            }
          }
        )
      },
    })
r
TS doesn't like that. I'm using it for the first time. Wants me to refactor for union types... This really is uphill 😆 I might leave union types until after the deadline But i like this (&&) pattern in this instance
l
might be just a syntax typo though, I've seen this pattern as well in our codebase too... try a simple change
Copy code
createdBy: {
          connect: {
            id: ctx.session.userId,
          },
        },
        ...(assignedTo.id && {
          assignedTo: {
            connect: {
              id: Number(assignedTo.id)
            }
          }
        })
essentially, if
assignedTo.id
exists, you're spreading an object `{ assignedTo: ... }`which should take care of the connecting
🙏 1
👍 1
r
Excellent! Thanks both 👏 With a bit type declaration it is working.