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

Scoped Many-to-many Relation #2881

Open
wadetandy opened this issue Jun 29, 2020 · 5 comments
Open

Scoped Many-to-many Relation #2881

wadetandy opened this issue Jun 29, 2020 · 5 comments
Labels
kind/feature A request for a new feature. team/client Issue for team Client. team/psl-wg topic: m:n many-to-many relations topic: schema

Comments

@wadetandy
Copy link

wadetandy commented Jun 29, 2020

Problem

Given a many-to-many relationship, I would like to be able to define a relationship that scopes to a subset of records based on a value in the join table.

Say I have models User and Group. I also have a join table GroupMembership:

model GroupMembership {
  userId String
  user    User @relation(fields: [userId], references: [id])
  groupId String
  group   Group @relation(fields: [groupId], references: [id])
  role String
}

The join table also has a role attribute. For our purposes say it can have a value of admin or member. I want to create two different relations on the Group model which take these into account:

model Group {
  # other stuff
  admins User[] # restrict this to group memberships with role == admin
  members User[] # restrict to group memberships with role == member
}

Suggested solution

I would like a way to specify a relation that is limited to a subset of the joined items. For anyone who has used Ruby-on-Rails/ActiveRecord, this is the equivalent of passing "scope" argument to a has_many through: association. Something like this might work for the example above:

model Group {
  admins Users[] @relation("GroupMemberships", references: [id], fields: [userId], where: { role: 'admin' })
}

## Alternatives
Currently I can do this manually in my code by creating a model for the join table and directly filtering on those records based on what I need, then jumping to the relation I actually care about.

## Additional context
n/a
@pantharshit00 pantharshit00 added kind/feature A request for a new feature. topic: schema labels Jul 1, 2020
@pantharshit00
Copy link
Contributor

pantharshit00 commented Jul 1, 2020

I would consider this to be related to #678 as I would usually use a sql view to achieve this. Embedding a query in the schema is not ideal in my opinion.

@cannikin
Copy link

cannikin commented Jul 7, 2020

But then you have business logic living in two places: your code and the database. I'd prefer that the database just be a dumb store of data and let all the logic for that defines how my application works to be in the application code itself.

@pantharshit00 pantharshit00 added the team/client Issue for team Client. label Apr 22, 2021
@janpio janpio added topic: m:n many-to-many relations team/psl-wg labels Jan 10, 2022
@codeninja
Copy link

codeninja commented Feb 7, 2022

Active Record provides a solid implementation of this.

has_many :orders, -> { where processed: true }
has_one :document, as: :logo,  -> { where tag: "logo" } 

AR specifies the business logic as a constraint on the association. When the association is queried, the conditional is appended. When the association is saved, the condition can be validated to ensure the Logo has a Tag == 'logo' and would throw an error.

This would be invaluable.

@codeninja
Copy link

But then you have business logic living in two places

I view this less as business logic and more as data integrity. Currently, if I define the concept of a logo as a Document having a tag='logo' there's no way to enforce via the schema that the logo must have a tag=logo to be considered a Logo type.

It would be possible to save a text file in place of the logo using Prisma without guarding logic. If this were defined on the schema directly your schema becomes the source of truth for the data integrity.

IMO the domain of concerns dictates that the database governs which data should pass into it's storage. The code should trust that the data being fed to it is structurally sound without needing to have external knowledge of how the data was previously processed.

IE: The database should be tight and restrictive as possible to enforce data integrity. This should happens on the Prisma schema layer rather than the execution layer.

Thus I believe this feature has merrit.

@said-alex
Copy link

It's a shame we don't have updates about this feature, it would be extremely useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature A request for a new feature. team/client Issue for team Client. team/psl-wg topic: m:n many-to-many relations topic: schema
Projects
None yet
Development

No branches or pull requests

6 participants