Royal
Royal

Reputation: 407

Data modeling in Prisma with relations

I have a problem understanding relations and data-modeling in Prisma. I have an "easy" example about two users who can participate in a tennis game. So i have:

Model User {
  id      Int @id 
  name    String 
}

Model Game { 
  id        Int @id 
  player1   PlayerInGame
  player2   PlayerInGame
}

Model PlayerInGame {
  id      Int @id
  player  User
  game    Game
}

It gives me this error:

Error validating model "Game": Ambiguous relation detected. The fields `player1` and `player2` in model `Game` both refer to `PlayerInGame`. Please provide different relation names for them by adding `@relation(<name>).

How can i fix this? Thanks in advance.

I tried to at a @relation field as well, but that gave me the following error:

model Game {
  id        Int          @id @default(autoincrement())
  createdAt DateTime     @default(now())
  player1   PlayerInGame @relation("player1")
  player2   PlayerInGame  @relation("player2")
}


Error validating model "Game": Automatic related field generation would cause a naming conflict. Please add an explicit opposite relation field.

Upvotes: 13

Views: 19467

Answers (3)

Cesarvspr
Cesarvspr

Reputation: 371

In my case, I was having this issue due to a FK being used in multiple fields in the same table. Whenever you have more than 1 relation to a model you need to provide a relation name to disambiguate the relation.

example:

model User {
  id    Int    @id
  name  String
  games Game[]
}

model Game {
  game_id    Int    @id
  name       String
  users      User[]
}

model PlayerInGame {
  id              Int   @id
  player          User
  gameAsPlayer1   Game? @relation("GamePlayer1", fields: [gameAsPlayer1Id], references: [game_id])
  gameAsPlayer1Id Int
  gameAsPlayer2   Game? @relation("GamePlayer2", fields: [gameAsPlayer2Id], references: [game_id])
  gameAsPlayer2Id Int
}

Upvotes: 4

mavilein
mavilein

Reputation: 11668

You can fix this error by providing two relation fields on PlayerInGame. You have two relation fields on Game. Hence you also need two opposite relation fields on PlayerInGame. In your application logic you have to ensure that only one of those two relation fields is set. So only PlayerInGame.gameAsPlayer1 or PlayerInGame.gameAsPlayer2 should be set according to your business domain.

model User {
  id      Int @id 
  name    String 
}

model Game { 
  id        Int @id 
  player1   PlayerInGame @relation("GamePlayer1")
  player2   PlayerInGame @relation("GamePlayer2")
}

model PlayerInGame {
  id            Int   @id
  player        User
  gameAsPlayer1 Game? @relation("GamePlayer1")
  gameAsPlayer2 Game? @relation("GamePlayer2")
}

Upvotes: 20

Ryan
Ryan

Reputation: 6327

The best way to do it would be a many-to-many relation. You can add as many users to a game as well in the future and will be scalable in turn.

model User {
  id    Int    @id
  name  String
  games Game[]
}

model Game {
  id    Int    @id
  name  String
  users User[]
}

You can then conditionally check the number of players in the game and limit them in your business logic.

Upvotes: 5

Related Questions