DEV Community

Cover image for It's Prisma Time - Create Relations
Luca Del Puppo for This is Learning

Posted on

It's Prisma Time - Create Relations

Hi Folks 👋
today I'll show you how to create relations among your entities. So don't waste time and let's start!

Before moving on, let me explain what we are going to do today.

  1. Create a relation 1-N among posts and comments
  2. Create a relation N-N among posts and authors
  3. Explain a relation 1-1

So get started from the first one.

1-N

To create the relation among Posts and Comments see the next code

model Post {
  ...
  comments  Comment[]
}

model Comment {
  id        Int @id @default(autoincrement())
  text      String
  post      Post @relation(fields: [postId], references: [id], onDelete: NoAction, onUpdate: Cascade)
  postId    Int
}
Enter fullscreen mode Exit fullscreen mode

As you can see in this example there are 3 steps

  1. Creation of the comment entity
  2. Creation of the relation between Post and Comment (@relation)
  3. Addition of the comments collection in the Post entity

Let's focus on the second point now

post      Post @relation(fields: [postId], references: [id], onDelete: NoAction, onUpdate: Cascade)
Enter fullscreen mode Exit fullscreen mode

this line of code says Prisma that in Comment entity there is a field postId related to the field id in Post entity. In this way you described the relation between Post and Comment entities. It's also possibile to describe what to do when a foreign key is deleted or updated using the keyword onDelete and onUpdate. This two commands could have 5 possibile values:

Not all of them are guaranteed in all the databases connector, but you can find here all the info about that.
Let's move on to the third point where you added this line of code

comments  Comment[]
Enter fullscreen mode Exit fullscreen mode

this line create a collection of comments inside the Post Entity like in every ORM that respects itself, so you can retrive by code the comments related to your post.

But let's move on and see the next relation.

N.B. it's possible to create a not mandatory foreign key too. In our context it makes no sense, but imagine that a comment should exist also without a Post. In order to map this relation you need to change the Comment entity in this way

model Comment {
  ...
  post      Post? @relation(fields: [postId], references: [id])
  postId    Int?
  ...
}
Enter fullscreen mode Exit fullscreen mode

Using the ? character, you should indicate to Prisma that the field can be null.

N-N

See the following code

model Post {
  id        Int @id @default(autoincrement())
  title     String
  content   String
  published Boolean
  comments  Comment[]
  authors   AuthorsOnPost[]
}

model Author {
  id        Int @id @default(autoincrement())
  firstName String
  lastName  String
  comments  Comment[]
  posts     AuthorsOnPost[]
}

model AuthorsOnPost {
  author    Author @relation(fields: [authorId], references: [id])
  authorId  Int
  post      Post @relation(fields: [postId], references: [id])
  postId    Int

  @@id([authorId, postId])
}
Enter fullscreen mode Exit fullscreen mode

As you can see there are 5 steps

  1. Creation of the Author entity
  2. Creation of the AuthorsOnPost entity
  3. Creation of the relation between Posts and Authors using the AuthorsOnPost entity
  4. Adding the collection of AuthorsOnPost in the Post Entity
  5. Adding the collection of AuthorsOnPost in the Authors Entity Let's start to see the second point where you created a new Entity with two fields: authorId and postId. authorId is a foreign key related to the Author Entity whereas postId is a foreign key related to the Post Entity, I think if you understood the previous paragraph, you don't have any problem to understand this. Using the @@id you indicated to prisma that the AuthorsOnPost had a primary key composed by this two fields, so you can have the same author and the same post only once. By doing that, you have created a relation N-N between Authors and Posts, so in your database now, you can have a Post with multiple Authors and an Author can contribute to multiple Posts. The last two steps instead allow you to have the collection of Authors related to a Post and viceversa.

1-1

For this particular relation I hope you have understood the syntax so I'll leave a symbolic example. We can say that you have a Post that can be in relation only with an Author and viceversa, you have to describe that relation like this

model Post {
  ...
  author    Author @relation(fields: [authorId], references: [id])
  authorId  Int
}

model Author {
  .....
  post      Post?
}
Enter fullscreen mode Exit fullscreen mode

I think it's not so hard to understand what I explained before, but it was necessary to bring this example too.

I think that's everything from the Relation's world with Prisma, but before updating the database, let me add to the project a package that creates the ER diagram of your database.

  1. Install the package prisma-erd-generator
yarn add -D prisma-erd-generator
Enter fullscreen mode Exit fullscreen mode
  1. update the prisma/schema.prisma with the following code
generator client {
  provider = "prisma-client-js"
}

generator erd {
  provider = "prisma-erd-generator"
}

...
Enter fullscreen mode Exit fullscreen mode

Now when you call the script npx prisma generate, Prisma generates for you also a file prisma/ERD.svg where you can see your ER Diagram.

Now it's time to upgrade your database and your types, so execute the next two scripts in your terminal

npx prisma generate
npx prisma db push
Enter fullscreen mode Exit fullscreen mode

Now your db is up to date and you have a new file like the next where there is your ER Diagram.
Prisma ERD

That's all for today guys, in the next article it's time to see how you can insert data in you table.

Before the greetings, if you are interested in seeing the prisma-erd-generator package you can find the repository here and if you want to leave a ⭐, press the button 😉

Ok, see you soon Guys
Bye Bye 👋

The code relatives to this article is available here

Discussion (0)