Eric Kidd
09/15/2021, 3:02 PMmodel Post {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
tags Tag[]
}
model Comment {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
tags Tag[]
}
model Tag {
resourceType String // One of "Post" or "Comment"
resourceId @db.Uuid
value String
}
For example, we could find all the tags associated with post a5c4b960-d5da-4e7b-abb5-0860bd85903d by querying:
SELECT * FROM Tag WHERE resourceType = 'Post' AND resourceId = 'a5c4b960-d5da-4e7b-abb5-0860bd85903d';
Ideally, I would like to able to write:
client.source_tables.findUnique({
where: { id: "a5c4b960-d5da-4e7b-abb5-0860bd85903d" },
include: { tags: true }
});
If I could do this, it would simplify a lot of code. The actual use case is more complicated than this, but that's the general idea. (The fact that resourceId is globally unique means that we have the option of ignoring resourceType, if that helps.)
I've read https://www.prisma.io/docs/concepts/components/prisma-schema/relations and Googled "prisma polymorphic relations", but I can't find a "best practice" for handling this situation with the current version of Prisma. Thank you for any insight anyone can provide!Eric Kidd
09/15/2021, 3:10 PMresources (Post | Comment)[] on Tag. I only want include: { tags: true } to work when loading a Post or Comment.
2. My id fields are globally unique across tables thanks to UUIDs.
This suggests that there might be some clunky workaround?Eric Kidd
09/15/2021, 5:03 PMresources (Post | Comment)[] on Tag, but can settle for separate posts and comments relations.Ryan
09/16/2021, 6:13 AMSELECT * FROM Tag WHERE resourceType = 'Post' AND resourceId = 'a5c4b960-d5da-4e7b-abb5-0860bd85903d';Eric Kidd
09/16/2021, 10:36 AMconst posts = client.Post.findMany({
where: { ... },
include: "tags",
};
...where Tag is:
model Tag {
resourceType String // One of "Post" or "Comment"
resourceId @db.Uuid // Reference to table defined by resourceType.
value String
}
It turns out that since UUIDs are globally unique, I can just ignore resourceType and build multiple ordinary relations on Tag using named relations. So I wind up with tag.posts, tag.comment, post.tags, comment.tags, and so on.Eric Kidd
09/16/2021, 10:38 AMTag-style polymorphism using foo_id and foo_type fields, where foo_type contains the table name being referred to, and foo_id contains the ID within that table. It's a common pattern (thanks to Rails and ActiveRecord), and it's not immediately obvious how to support it using Prisma.
But I have it working nicely for our use case. No worries, and thank you for the help!