🙆♀️
【Drizzle ORM】NextJs14 と Drizzle ORM【#26 Profile Table Relation】
【#26 Profile Table Relation】
YouTube: https://youtu.be/3XYTK-kqKW4
今回はユーザーデータの取得の際に
プロフィールのデータも取得する方法について実装していきます。
こちらは「leftJoin」か「with」を使用します。
「innerJoin」を使用するとプロフィールのデータが存在しない場合に、
ユーザーのデータも取得されない場合があるので注意が必要です。
「leftJoin」と「with」で取得時のデータの構造が異なりますので、
こちらも注意が必要です。
app/api/[[...route]]/users.ts
import { Hono } from "hono";
import { z } from "zod";
import { zValidator } from "@hono/zod-validator";
import { clerkMiddleware, getAuth } from "@hono/clerk-auth";
import { db } from "@/db/drizzle";
import { profile, users } from "@/db/schema";
import { eq } from "drizzle-orm";
const app = new Hono()
.get("/", async (c) => {
const data = await db.select().from(users);
return c.json({
data,
});
})
.get("/me", clerkMiddleware(), async (c) => {
const auth = getAuth(c);
if (!auth?.userId) {
return c.json({ error: "Unauthorized" }, 401);
}
// const [data] = await db
// .select()
// .from(users)
// .leftJoin(profile, eq(users.id, profile.userId))
// .where(eq(users.clerkId, auth.userId));
const data = await db.query.users.findFirst({
where: eq(users.clerkId, auth.userId),
with: {
profile: {
columns: {
message: true,
},
},
},
});
if (!data) {
return c.json({ error: "User not found" }, 404);
}
return c.json({ data });
})
.get(
"/:id",
zValidator(
"param",
z.object({
id: z.string(),
})
),
async (c) => {
// const id = c.req.param("id");
const { id } = c.req.valid("param");
const [data] = await db.select().from(users).where(eq(users.id, id));
if (!data) {
return c.json({ error: "User not found" }, 404);
}
// if (data.length === 0) {
// return c.json({ error: "User not found" }, 404);
// }
return c.json({
user: data,
});
}
);
export default app;
「with」を使用する場合は、
「users」と「profile」のテーブルそれぞれに
Relationの設定をする必要があります。
「profile」のRelationの設定として、
「profileRelations」を追記しています。
こちらはマイグレーションをしなくても動作します。
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 profileRelations = relations(profile, ({ one, many }) => ({
user: one(users, {
fields: [profile.userId],
references: [users.id],
}),
}));
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