prisma / language-tools

🌐 Prisma Language Tools = Language Server and Prisma's VS Code extension.
https://marketplace.visualstudio.com/items?itemName=Prisma.prisma
Apache License 2.0
258 stars 37 forks source link

VSCode extension adds new fields to a model when saving file #206

Closed yantakus closed 4 years ago

yantakus commented 4 years ago

I have the following model:

model Video {
  ytId       String  @id
  uploader   User    @relation("UserVideos", fields: [uploaderId], references: [uid])
  uploaderId String
}

model User {
  uid       String  @id
  videos    Video[] @relation("UserVideos")
  bookmarks Video[]
}

When I save the file, VSCode extension adds the following fields to the Video model:

  User       User?   @relation(fields: [userUid], references: [uid])
  userUid    String?

Why does this happen? Am I doing something wrong or is this a bug?

yantakus commented 4 years ago

When I added the following fields myself:

model Video {
  ...
  bookmarkers User[]     @relation("UserBookmarks")
}
model User {
  ...
  bookmarks Video[] @relation("UserBookmarks")
}

this doesn't happen anymore.

Seems that prisma is missing these fields for correct reference, so the extension is configured to add it automatically.

It would be nice to have some sort of notification about why this is necessary when this happens.

yantakus commented 4 years ago

The only concern left is if the automatically added fields are correct. I don't think so. It adds User and userUid fields to the Video model that are singular while a video can be bookmarked by multiple users. So it seems it should be fixed anyway.

sol-idsnake commented 4 years ago

I just tested this:

model Test {
  id        String   @default(cuid()) @id
}

model Tester {
  id        String   @default(cuid()) @id
}

When adding tests Tester[] to the Test model, vscode automatically adds:

  Test     Test? @relation(fields: [testId], references: [id])
  testId  String?

When trying to create a relation on TESTER first, vscode doesn't add the correlating code to model Test.

The auto-generated code seems correct to me, this is making your life easier. Are you saying the fields are incorrect?

yantakus commented 4 years ago

If I understand everything correctly, in the code which is automatically added:

User       User?   @relation(fields: [userUid], references: [uid])
userUid    String?

User and userUid are single values, where a video can have only one user (bookmarker) while it should be many to many relation:

Video {
  bookmakers: User[]

and

User {
  bookmarks: Video[]
}

And in your example it's also single Test, not Test[].

mavilein commented 4 years ago

Hey @yantakus,

thanks for reaching out to us. :pray:

Seems that prisma is missing these fields for correct reference, so the extension is configured to add it automatically.

Yes you are right. We decided that a Prisma schema must always be explicit about relations. A relation consists of the two relation fields of the related models. In your case User.bookmarks was there but the related field on the model Video was missing. Hence the field Video.User was added. We added this feature of automatically adding those fields because we think it is quite annoying having to always specify both sides of a relation.

The only concern left is if the automatically added fields are correct. I don't think so. It adds User and userUid fields to the Video model that are singular while a video can be bookmarked by multiple users. So it seems it should be fixed anyway.

The field that gets added is actually correct. When we add a missing relation field we need to decide whether a relation is one to many or many to many. Our simple rule is that we always choose one to many. So in your case we add a singular field because the existing field is a list. Here are some reasons for this rule:

So you generally have two options on how to deal with this:

  1. Always add both relation fields before saving your schema in vs code.
  2. Change those generated fields once they have been added to your schema. (Like you already found out yourself)