Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MongoDb: 2-way Embedded M:N Relations #2671

Merged
merged 2 commits into from
Feb 11, 2022

Conversation

pimeys
Copy link
Contributor

@pimeys pimeys commented Feb 9, 2022

Sets to stone how these should look like, instead of hacking them together. Introduces a new many-to-many relation definition only for MongoDB:

model A {
  id    String   @id @map("_id") @default(auto()) @test.ObjectId
  b_ids String[] @test.ObjectId
  bs    B[]      @relation(fields: [b_ids], references: [id])
}

model B {
  id    String   @id @map("_id") @default(auto()) @test.ObjectId
  a_ids String[] @test.ObjectId
  as    A[]      @relation(fields: [a_ids], references: [id])
}

Both models hold a list of identifiers in an array. Using this list, we build a relation to another model pointing to an identifier of that model. From the other model we again define a relation from an array to an identifier. This forms an embedded 2-way many-to-many relation with the following rules:

  • Detected as an embedded relation if any of the sides defines fields argument.
  • Only allowed in MongoDb.
  • Both sides must define fields and references.
  • The fields argument must point to an array scalar field.
  • The references argument must point to an id field that must be of same type as the fields array scalar.
  • No referential actions are allowed in these relations for now.

Closes: prisma/prisma#11553

@pimeys pimeys added this to the 3.10.0 milestone Feb 9, 2022
@pimeys pimeys force-pushed the parser-database/2-way-embedded-many-to-many-relations branch 5 times, most recently from 8ff5a08 to 339549e Compare February 10, 2022 17:31
Sets to stone how these should look like, instead of hacking them together.
Introduces a new many-to-many relation definition only for MongoDB:

```prisma
model A {
  id    String   @id @Map("_id") @default(auto()) @test.ObjectId
  b_ids String[] @test.ObjectId
  bs    B[]      @relation(fields: [b_ids], references: [id])
}

model B {
  id    String   @id @Map("_id") @default(auto()) @test.ObjectId
  a_ids String[] @test.ObjectId
  as    A[]      @relation(fields: [a_ids], references: [id])
}
```

Both models hold a list of identifiers in an array. Using this list, we build a
relation to another model pointing to an identifier of that model. From the
other model we again define a relation from an array to an identifier. This
forms an embedded 2-way many-to-many relation with the following rules:

- Detected as an embedded relation if any of the sides defines `fields` argument.
- Only allowed in MongoDb.
- Both sides must define `fields` and `references`.
- The `fields` argument must point to an array scalar field.
- The `references` argument must point to an id field that must be of same type
  as the `fields` array scalar.
- No referential actions are allowed in these relations for now.
@pimeys pimeys force-pushed the parser-database/2-way-embedded-many-to-many-relations branch from 339549e to af852b7 Compare February 10, 2022 17:42
@pimeys pimeys marked this pull request as ready for review February 10, 2022 17:43
if !relation_field.references_singular_id_field() {
ctx.push_error(DatamodelError::new_validation_error(
format!(
"Many to many relations must always reference the id field of the related model. Change the argument `references` to use the id field of the related model `{}`. But it is referencing the following fields that are not the id: {}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Many to many relations must always reference the id field of the related model. Change the argument `references` to use the id field of the related model `{}`. But it is referencing the following fields that are not the id: {}",
"Implicit many to many relations must always reference the id field of the related model. Change the argument `references` to use the id field of the related model `{}`. But it is referencing the following fields that are not the id: {}",

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tbd but I think it's all many-to-many relations

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...that was agreed on

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't know who to believe then :D #2671 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you might actually be right now. If this also applies to the new MongoDB relation, that one is not really implicit as it has the explicit arrays for storing the references.

Copy link
Contributor

@tomhoule tomhoule left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome

@pimeys pimeys requested a review from a team as a code owner February 11, 2022 11:11
@pimeys pimeys merged commit b70a888 into main Feb 11, 2022
@pimeys pimeys deleted the parser-database/2-way-embedded-many-to-many-relations branch February 11, 2022 11:50
@Jolg42 Jolg42 modified the milestone: 3.10.0 Feb 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement datamodel parser validations for two-way embedded many-to-many relations on MongoDB
5 participants