Many to many on the same model, multi directional?

I have a fairly simple question and have been struggling long enough that I thought it warranted a question. I have a simple concept: one model is an Artist and I want to have a “related artist” array. I am familiar with the many to many and relations attribute to set up and have both models populate. I have a RelatedArtist model that houses both an artist and a related artist on it. It works fine and I’m able to join the records using this model. What I’m confused with or wondering is this: Depending on how I connect the model, the children are different when I retrieve the record. for example, if I connect artist A to artist B, and in artist A want to pull the related model for B, I use “artist.relatedArtists” to pull the data. However, in model B, I have a different field name so i use “artist.artists” to pull artist A. Is there a more clever or better way to do this?
1 Reply
armorform
armorformOP9mo ago
model Artist {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

slug String @unique

relatedArtists RelatedArtist[] @relation("relatedArtist")
artists RelatedArtist[] @relation("artists")
}

model RelatedArtist {
relatedArtistId String
relatedArtist Artist @relation("relatedArtist", fields: [relatedArtistId], references: [id], onDelete: Cascade, onUpdate: Cascade)

artistId String
artist Artist @relation("artists", fields: [artistId], references: [id], onDelete: Cascade, onUpdate: Cascade)

@@id([artistId, relatedArtistId])
}
model Artist {
id String @id @default(uuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

slug String @unique

relatedArtists RelatedArtist[] @relation("relatedArtist")
artists RelatedArtist[] @relation("artists")
}

model RelatedArtist {
relatedArtistId String
relatedArtist Artist @relation("relatedArtist", fields: [relatedArtistId], references: [id], onDelete: Cascade, onUpdate: Cascade)

artistId String
artist Artist @relation("artists", fields: [artistId], references: [id], onDelete: Cascade, onUpdate: Cascade)

@@id([artistId, relatedArtistId])
}
^ here's what the schema looks like, and I think what I'm better getting at is how to avoid having to do this:
relatedArtists: {
include: {
artist: true,
relatedArtist: true,
},
},
relatedArtists: {
include: {
artist: true,
relatedArtist: true,
},
},
What I'm doing now is basically returning an object that is an array of both include fields:
relatedArtists: [...artist.relatedArtists, ...artist.artists].filter(
(n) => n,
),
relatedArtists: [...artist.relatedArtists, ...artist.artists].filter(
(n) => n,
),
And as you can imagine, it's kind of annoying / messy. What I'd like to do is quite simple; just have the same "include" field returned on both models so I don't have to do this messy back and forth juggling between which "side" the relation was originally created on. Anyways, thanks in advance SO much for your help! I promise I've already spent a few hours trying to wrap my head around this...
Want results from more Discord servers?
Add your server