prisma1 icon indicating copy to clipboard operation
prisma1 copied to clipboard

Allow multiple unidirectional relations of the same type

Open notadamking opened this issue 6 years ago • 17 comments

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.

notadamking avatar Feb 15 '18 07:02 notadamking

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.

marktani avatar Mar 29 '18 10:03 marktani

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.

leesiongchan avatar Apr 21 '18 15:04 leesiongchan

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?

murdockq avatar May 10 '18 21:05 murdockq

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 avatar May 11 '18 15:05 murdockq

@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?

rschwabco avatar Jul 11 '18 17:07 rschwabco

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

AustinGomez avatar Nov 22 '18 00:11 AustinGomez

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

hvasconcelos avatar Dec 21 '18 17:12 hvasconcelos

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

Quadriphobs1 avatar Jan 16 '19 16:01 Quadriphobs1

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

seunggs avatar Feb 23 '19 18:02 seunggs

Same issue.

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

tsarchghs avatar Mar 29 '19 19:03 tsarchghs

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") } `

sdeagh avatar May 16 '19 13:05 sdeagh

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.

nathanburgess avatar Jul 09 '19 16:07 nathanburgess

+1 I also need this

vjsingh avatar Aug 16 '19 21:08 vjsingh

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

developerk786 avatar Aug 21 '19 04:08 developerk786

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.

nathanburgess avatar Aug 21 '19 20:08 nathanburgess

+1

sasha240100 avatar Nov 24 '19 10:11 sasha240100

+1

ssteiger avatar Mar 18 '20 20:03 ssteiger