drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
23.22k stars 565 forks source link

[DOCUMENTATION]: Typo in the code #2840

Open MrOxMasTer opened 3 weeks ago

MrOxMasTer commented 3 weeks ago

What version of drizzle-orm are you using?

0.33.0

What version of drizzle-kit are you using?

0.23.0

Describe the Bug

https://orm.drizzle.team/docs/rqb#foreign-keys

export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name'),
});
export const usersRelations = relations(users, ({ one, many }) => ({
  profileInfo: one(users, {  // the table is specified incorrectly
    fields: [profileInfo.userId],
    references: [users.id],
  }),
}));
export const profileInfo = pgTable('profile_info', {
  id: serial('id').primaryKey(),
  userId: integer("user_id"),
  metadata: jsonb("metadata"),
});

image image

The types match image

Expected behavior

No response

Environment & setup

No response

demize commented 1 week ago

Yeah, this just tripped me up pretty significantly. It doesn't help that Typescript's errors are so opaque; the massive error makes it hard to figure out what it's complaining about...

I believe the example is intended to look more like this:

export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  name: text("name"),
});

export const usersRelations = relations(users, ({ one, many }) => ({
  profileInfo: one(profileInfo, {
    fields: [users.id],
    references: [profileInfo.userId],
  }),
}));

export const profileInfo = pgTable("profile_info", {
  id: serial("id").primaryKey(),
  userId: integer("user_id").references(() => users.id, {
    onDelete: "cascade",
  }),
  metadata: jsonb("metadata"),
});

This does ensure that when you do db.query.users.findFirst({ with: { profileInfo: true } }) (or other queries), it returns the profile info for the user, and it's consistent with the earlier documentation where profileInfo was introduced. (which had relations(users, ({one}) => ({profileInfo: one(profileInfo)})).

MrOxMasTer commented 1 week ago

I believe the example is intended to look more like this:

It actually looks very strange. In fact, you have made the user id dependent on the "userId" field in profileInfo, which logically should be the other way around

It seems to me that this is a more correct example:

export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  name: text("name"),
});

export const usersRelations = relations(users, ({ one, many }) => ({
  profileInfo: one(profileInfo)
}));

export const profileInfo = pgTable("profile_info", {
  id: serial("id").primaryKey(),
  userId: integer("user_id").references(() => users.id, {
    onDelete: "cascade",
  }),
  metadata: jsonb("metadata"),
});

export const profileInfoRelations = relations(profileInfo, ({ one, many }) => ({
  user: one(users, {
    fields: [profileInfo.id],
    references: [users.id],
  }),
}))