Do I need to use Prisma's connect & disconnect API? Or is it not safe to just update my Relations via IDs as strings?

620 Views Asked by At

I am using prisma + mysql (on planetscale). When I link two items that are in different tables, I normally use connect or disconnect:

const getUser = await prisma.user.update({
  where: {
    id: 9
  },
  data: {
    posts: {
|      connect: {
|        id: 11
|      },
      create: {
        title: "My new post title"
      }
    }
  }
})

I am wondering whether that's necessary or why that's necessary?

I also noticed that I can just update records in my database by updating the id (as a plain string), and it will still work. e.g.:

// example for updating a one-to-many relationship:
const getUser = await prisma.user.update({
  where: {
    id: 9
  },
  data: {
    postId: "123192312i39123123"
    }
  }
})

... or if it's an explicit many-to-many relation, I can just edit the row in the relation-table & update the id.

Is this a bad way of doing things? Am I going to break something later down the line in doing it this way?

2

There are 2 best solutions below

0
On

While you can manually update IDs, using connect and disconnect has a few advantages:

  • First and foremost, connect throws an exception if any of the connected records do not exist.

    Because Prisma supports multiple DBs, I assume they do this check in their own engine, rather than relying on the DB to check the foreign key constraint.

  • It can be used to update a specific entity plus one-to-one, one-to-many and many-to-many relationships with a single interface and without having to write a separated query for the junction table:

    const result = await prisma.user.update({
      where: {
        email: '[email protected]',
      },
      data: {
        lastSeen: Date.now(),
        featuredPost: {
          connect: { id: 8 },
        },
      },
    })
    
    const result = await prisma.user.update({
      where: {
        email: '[email protected]',
      },
      data: {
        lastSeen: Date.now(),
        posts: {
          connect: [{ id: 8 }, { id: 9 }, { id: 10 }],
        },
      },
    })
    
  • You can also use connectOrCreate to easily create an entity if it doesn't exist already.

  • For disconnect, you also have single interface that works with one-to-one, one-to-many and many-to-many relationships, and you can easily disconnect all related records too:

    const result = await prisma.user.update({
      where: {
        email: '[email protected]',
      },
      data: {
        posts: {
          set: [],
        },
      },
    })
    

You can read more in the officials docs.

0
On

Your cloud provider is not relevant in the context of the question. It will not affect how your framework(prisma) behaves in updates.

I am wondering whether that's necessary or why that's necessary?

You have a user with a one to many relation: user => n posts.
You have an existing post in the db, and you want to add that post to the posts collection of a user.

That posts relation can be either explicit or implicit. The connect clause handles the addition of relation:

{
  posts: {
    connect: { id: 11 }
  }
}

Without using the connect you'd have to create a new post:

{
  posts: {
    create: {
      title: "My new post title"
    }
  }
}

update records in my database by updating the id (as a plain string)

Not sure what you mean here, mind sharing the schema?

or if it's an explicit many-to-many relation, I can just edit the row in the relation-table & update the id

If it's explicit many-to-many then it's OK to manually edit the id fields. As long as the ids are found and the relation makes sense, there's no problem with manual updates.