How to make one object have 2 different relationships with another object.

I have 2 tables Product and Media. The product has a thumbnail and also images of the product. The thumbnail is one media and images are many media. So in short I have to have one-to-one relation between Product.thumbnail and Media, and a one-to-many relation between Product.images and Media. My code follows the docs about relations but it does not work (my guess because of circular references).
export const Product = pgTable("product", {
id: uuid("id").primaryKey().defaultRandom(),
title: varchar("title", { length: 128 }).notNull(),
description: varchar("description", { length: 1024 }),
// the product "owns" the Media in thumbnail
thumbnailId: uuid("thumbnail_id").references(() => Media.id),
})

export const Media = pgTable("media", {
id: uuid("id").primaryKey().defaultRandom(),
url: varchar("url", { length: 512 }).notNull(),
// needs to reference productId to correctly implement a one-to-many relation
productId: uuid("product_id").references(() => Product.id),
})

export const ProductRelations = relations(Product, ({ one, many }) => ({
thumbnail: one(Media, {
fields: [Product.thumbnailId],
references: [Media.id],
}),
images: many(Media),
}))

export const MediaRelations = relations(Media, ({ one, many }) => ({
productThumbnail: one(Product),
productImages: one(Product, {
fields: [Media.productId],
references: [Product.id],
}),
}))
export const Product = pgTable("product", {
id: uuid("id").primaryKey().defaultRandom(),
title: varchar("title", { length: 128 }).notNull(),
description: varchar("description", { length: 1024 }),
// the product "owns" the Media in thumbnail
thumbnailId: uuid("thumbnail_id").references(() => Media.id),
})

export const Media = pgTable("media", {
id: uuid("id").primaryKey().defaultRandom(),
url: varchar("url", { length: 512 }).notNull(),
// needs to reference productId to correctly implement a one-to-many relation
productId: uuid("product_id").references(() => Product.id),
})

export const ProductRelations = relations(Product, ({ one, many }) => ({
thumbnail: one(Media, {
fields: [Product.thumbnailId],
references: [Media.id],
}),
images: many(Media),
}))

export const MediaRelations = relations(Media, ({ one, many }) => ({
productThumbnail: one(Product),
productImages: one(Product, {
fields: [Media.productId],
references: [Product.id],
}),
}))
These lines cause a TS error:
thumbnailId: uuid("thumbnail_id").references(() => Media.id),
productId: uuid("product_id").references(() => Product.id),
thumbnailId: uuid("thumbnail_id").references(() => Media.id),
productId: uuid("product_id").references(() => Product.id),
Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
How do I correctly implement 2 different relations between 2 tables?
9 Replies
xxxxx
xxxxx2mo ago
bump
rphlmr ⚡
rphlmr ⚡2mo ago
https://drizzle.run/ryxw1u9ieaf45i9owbpwbw70 It should do what you expect Note that you will have the thumnail in images too. If you want to discard it for some reason, you should add a discriminent column (like a type)
xxxxx
xxxxx2mo ago
this seems a bit too complicated is my approach good for this?
rphlmr ⚡
rphlmr ⚡2mo ago
with a discriminent on media type: https://drizzle.run/kjm4cv2t22iwmzdcmmnhcc3y What do you find complicated? The example or adding a more complexity filtering images and thumbnail?
xxxxx
xxxxx2mo ago
the relationship I am building here. I haven't seen anything like it in the docs and the ai on the website couldn't build it properly. maybe my approach from the start of creating this is wrong.
rphlmr ⚡
rphlmr ⚡2mo ago
no it is good. We lack example because we can't cover every use cases if you look at what you tried and the playground, it is exactly what you did + some fixes not obvious just reading the doc
xxxxx
xxxxx2mo ago
okay thank you. I will study the examples you provided me
rphlmr ⚡
rphlmr ⚡2mo ago
the images (many) and productImages (one) need the same relation name to glue all the thing + some AnyPgColumn fro typescript If you want more control, you can also have a separate table for thumbnails. Just a matter of choice
xxxxx
xxxxx2mo ago
this might actually be what I do in the end.
Want results from more Discord servers?
Add your server