Prisma1: Allow multiple unidirectional relations of the same type

Created on 15 Feb 2018  路  17Comments  路  Source: prisma/prisma1

Feature Request

What feature are you missing?

Currently it is impossible to define multiple unidirectional relations of the same type within another type. For example:

type ContainerType {
  someObject: SomeType
  anotherObject: SomeType
}

This gives the error The relation field 'someObject' must specify a '@relation' directive
But when @relation is added to both objects:

type ContainerType {
  someObject: SomeType @relation(name: "ContainerTypeSomeObject")
  anotherObject: SomeType @relation(name: "ContainerTypeAnotherObject")
}

The error A relation directive with a name must appear exactly 2 times. is thrown. I cannot seem to find a work around in the documentation, so I assume this is currently not possible.

How could this feature look like in detail? Tradeoffs?

There needs to be a way to add multiple unidirectional relations of the same type to another type. The above example would work if the requirement for relation directives to be bi-directional was removed.

Use case 1:

A user in an application has a profile in which they can set multiple phone numbers (mobile, home, etc.). The type for this profile could look as follows:

type Profile {
  id: ID! @unique
  mobilePhone: Phone
  homePhone: Phone
  otherPhone: Phone
}

The problem here is that a Phone object doesn't care about where it is contained. In fact, the same Phone object might be referenced by many types of objects in the database. In this case, it doesn't make sense to add a property to the Phone type for every possible property of every type that might refer to it. For example, consider we have three different types of profiles in our database that all have 3 properties referring to a Phone type. This means we're going to have to add 9 new properties to our Phone type, all of which bloats our codebase and API with queries and resolvers that will never be used.

kinfeature

Most helpful comment

@murdockq I don't think this solution is viable for complex enough schemas. Things get hairy when you look at multiple overlapping outgoing types. Having to specify unique bi-directional relations for each is not possible in those cases.

@marktani - Are there plans to address this issue?

All 17 comments

Thanks for bringing this up, @adamjking3.

This behaviour stems from the fact that the two pairs of two fields for two relations between the same types cannot be associated to each other unambiguously.

Consider this:

  • You _cannot_ define two relations between the same types _without_ specifying @relation.
  • You _can_ define two relations between the same types by specifying @relation on _both sides of the relation_.

In your example, you are only specifying @relation on _one side of the relation_. That's why you receive the error message.

Please add the @relation directive on the other side as well, that should get you going.

Do we have a plan for this to be fixed? This look like a very important feature, end up I have to write a lot of unnecessary fields just to make it passes.

I still can't quite see how to make this work with the bidirectional limitation:

type Profile {
  id: ID! @unique
  name: String
  description: String
  banner: File @relation(name: "Banner")
  avatar: File @relation(name: "Avatar")
}

type File {
  id: ID! @unique
  name: String!
  contentType: String!
  url: String!
}

Consider this relationship, I do not think it is wise to add @relation(name: "Avatar") to the type File as it is usage agnostic. The only viable options I have is to have a banner: String and avatar: String that stores the ID to the file which doesn't do any type checking, and requires running two queries to get the full object back with the files.

Any other suggested work around I might not know about?

Looks like we found an acceptable work around by having an intermediate type that holds the reused File object. Incase someone else runs into the same problem and needs a solution.

type Profile {
  id: ID! @unique
  name: String
  description: String
  banner: Banner
  avatar: File
}

type Banner {
 id: ID! @unique
 file: File
}

type File {
  id: ID! @unique
  name: String!
  contentType: String!
  url: String!
}

@murdockq I don't think this solution is viable for complex enough schemas. Things get hairy when you look at multiple overlapping outgoing types. Having to specify unique bi-directional relations for each is not possible in those cases.

@marktani - Are there plans to address this issue?

Seems like the only way to really do it is as above... Unfortunate

The problem seems to be solved on the latest prisma version.

What of a situation when you want to make CASCADE relationship

type Profile {
  id: ID! @unique
  name: String
  description: String
  banner: File @relation(name: "Banner", onDelete: CASCADE)
  avatar: File @relation(name: "Avatar", onDelete: CASCADE)
}

type File {
  id: ID! @unique
  name: String!
  contentType: String!
  url: String!
}

The prisma wont deploy with this because there is no vice-versa relation on the File, Is there any way you can as well do this type of relationship

Has there been any progress with this? Having the same issues - this is a pretty common use case especially with images as commented above.

Same issue.

type Story {
    id: ID! @unique
    video: File! @relation(name: "StoryVideoFile")
    thumbnail: File! @relation(name: "StoryThumbnailFile")
}

Is this still an issue? Having the same problem:
`type Club {
id: ID! @id
name: String!
}

type Fixture {
id: ID! @id
date: DateTime!
homeClub: Club! @relation(name: "HomeClub")
awayClub: Club! @relation(name: "AwayClub")
}
`

Are there any plans to fix this? This is a pretty common scenario that's widely supported in databases, it makes sense that Prisma could handle it as well.

+1 I also need this

wth when will this feature be implemented working on a production-ready app and the deadline is next months!

wth when will this feature be implemented working on a production-ready app and the deadline is next months!

Maybe don't use something that lacks a feature you need in your production toolset? I'm watching this project because I'd like to use it, but currently, I'm not using it because it's just not good enough yet.

+1

+1

Was this page helpful?
0 / 5 - 0 ratings

Related issues

thomaswright picture thomaswright  路  3Comments

hoodsy picture hoodsy  路  3Comments

marktani picture marktani  路  3Comments

AlessandroAnnini picture AlessandroAnnini  路  3Comments

marktani picture marktani  路  3Comments