🙌

【Drizzle ORM】NextJs14 と Drizzle ORM【#16 Drizzle Many to Many 】

2024/08/16に公開

【#16 Drizzle Many to Many 】

YouTube: https://youtu.be/2xIDAV2xhPg
https://youtu.be/2xIDAV2xhPg

今回も引き続き、Drizzle ORM のスキーマの設定について見ていきます。
今回は「Many-to-many」のリレーションの設定について実装をしていきます。

https://orm.drizzle.team/docs/rqb#many-to-many

「usersToGroups」、「groups」のテーブルを作成して、
「usersToGroups」と「groups」、「users」のテーブルそれぞれに対して紐づけを行います。

db/schema.ts
import { relations } from "drizzle-orm";
import { pgTable, text, timestamp, primaryKey } from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";

export const users = pgTable("users_table", {
  id: text("id").primaryKey(),
  clerkId: text("clerk_id").notNull().unique(),
  name: text("name").notNull(),
  email: text("email").notNull().unique(),
  imageUrl: text("image_url"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at")
    .notNull()
    .$onUpdate(() => new Date()),
});

export const usersRelations = relations(users, ({ one, many }) => ({
  profile: one(profile),
  posts: many(posts),
  comments: many(comments),
  usersToGroups: many(usersToGroups),
}));

export const insertUsersSchema = createInsertSchema(users);

export const profile = pgTable("profile_table", {
  id: text("id").primaryKey(),
  userId: text("user_id").references(() => users.id, { onDelete: "cascade" }),
  message: text("message"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at")
    .notNull()
    .$onUpdate(() => new Date()),
});

export const insertProfileSchema = createInsertSchema(profile);

export const posts = pgTable("posts_table", {
  id: text("id").primaryKey(),
  userId: text("user_id").references(() => users.id),
  content: text("content"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at")
    .notNull()
    .$onUpdate(() => new Date()),
});

export const postsRelations = relations(posts, ({ one, many }) => ({
  author: one(users, {
    fields: [posts.userId],
    references: [users.id],
  }),
  comments: many(comments),
}));

export const insertPostsSchema = createInsertSchema(posts);

export const comments = pgTable("comments_table", {
  id: text("id").primaryKey(),
  userId: text("user_id").references(() => users.id),
  postId: text("post_id").references(() => posts.id),
  comment: text("comment"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at")
    .notNull()
    .$onUpdate(() => new Date()),
});

export const commentsRelations = relations(comments, ({ one, many }) => ({
  user: one(users, {
    fields: [comments.userId],
    references: [users.id],
  }),
  post: one(posts, {
    fields: [comments.postId],
    references: [posts.id],
  }),
}));

export const insertCommentsSchema = createInsertSchema(comments);

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

export const groupsRelations = relations(groups, ({ many }) => ({
  usersToGroups: many(usersToGroups),
}));

export const usersToGroups = pgTable(
  "users_to_groups",
  {
    userId: text("user_id")
      .notNull()
      .references(() => users.id),
    groupId: text("group_id")
      .notNull()
      .references(() => groups.id),
  },
  (t) => ({
    pk: primaryKey({ columns: [t.userId, t.groupId] }),
  })
);

export const usersToGroupsRelations = relations(usersToGroups, ({ one }) => ({
  group: one(groups, {
    fields: [usersToGroups.groupId],
    references: [groups.id],
  }),
  user: one(users, {
    fields: [usersToGroups.userId],
    references: [users.id],
  }),
}));

Discussion