Skip to content

[Feature Request] One way relations without overhead #2681

@JuzioMiecio520

Description

@JuzioMiecio520

Problem

In many cases a user may want to create a one-way relationship between models, for example:

model User {
  id    Int    @id
  image Image?
}

model Product {
  slug  String @id
  image Image?
}

model Post {
  id     Int     @id
  images Image[]
}

model Image {
  id          String   @id
  path        String
  userId      Int?     @unique
  user        User?    @relation(fields: [userId], references: [id])
  productSlug String?  @unique
  product     Product? @relation(fields: [productSlug], references: [slug])
  postId      Int?
  post        Post?    @relation(fields: [postId], references: [id])
}

The image model is over-specified and causes not only headaches when designing models, but also later when referencing the data.
This issue has been a known limitation of Prisma for over 7 years and has over 100 comments as seen in #2018.

Proposed solution

Best solution would be to implicitly recognise relations, and if the user does not explicitly define a back-relation, then ZenStack should omit relation fields in the underlying model. This way, model from before would look like this:

model User {
  id    Int    @id
  image Image?
}

model Product {
  slug  String @id
  image Image?
}

model Post {
  id     Int     @id
  images Image[]
}

model Image {
  id          String   @id
  path        String
}

Thus, when referencing User we have access to Image, but when referencing Image we do not necessarily have references to User/Product/Post.

I do not see any side effects with this solution and it should not introduce any breaking changes. If some were to come up during development, ZenStack could implement some attribute, like @relation(oneWay: true) to make sure the user knows what they're doing and explicitly configure the model with one way relation.

Alternatives

There really aren't any good alternatives, as seen in Prisma issue referenced earlier, the best solution are janky TypeScript types like Omit or as any all over the place, which introduce bugs and break with every change to the model. These also does not remove the problem of very long model definitions.

Additional considerations

It would also be great if it were possible to define explicit many-to-many relations one way. As far as I'm aware, my solution would be a drop-in replacement and should work out-of-the-box, but this may need to be additionally though through.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions