Prisma で定義したモデルがプロパティとして enum を持っていたとします。それをソートキーとして使用したい場面がありました。この記事では emum をキーとして、配列のオブジェクト群を Array.prototype.sort で並び替える方法を紹介します。
スキーマ定義
スキーマ内で以下のようなレベル (enum) とメンバー (model) を定義したものとします。
/prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
// Enum は MySQL または PostgreSQL でのみサポートされる。
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// Enum で 4 段階のレベル (入門、初級、中級、上級) を定義する。
enum Level {
BEGINNER
ELEMENTARY
INTERMEDIATE
ADVANCED
}
// レベルをフィールドに持つメンバーを定義する。
model Member {
id Int @id @default(autoincrement())
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
name String
level Level @default(BEGINNER)
// ^^^^^^ レベルを参照する。
@@map("members")
}
実際のコード
prisma generate
を実行すると、prisma/client
以下に Level というオブジェクトとその型定義が生成されます。
/node_modules/.prisma/client/index.d.ts
export const Level: {
BEGINNER: 'BEGINNER',
ELEMENTARY: 'ELEMENTARY',
INTERMEDIATE: 'INTERMEDIATE',
ADVANCED: 'ADVANCED'
};
export type Level = (typeof Level)[keyof typeof Level]
sort 関数は並び順を決めるコールバック関数 (compareFn) を引数として受け取ることができます。compareFn は配列の要素を 2 つ受け取り、その返り値によって要素を並び替えるのですが、オブジェクトのままでは意図した通りに比較できません。
ここで比較可能なインデックスを持つ配列に変換することがポイントとなります。今回はレベルの昇順 (入門 > 初級 > 中級 > 上級) に並び替えたいので、以下のようなコードを書きました。
import { $Enums } from '@prisma/client';
import type { Member } from '@prisma/client';
export const sortMembersByLevel = (members: Member[]): Member[] => {
// 並び替えたい順に enum 値を配列に格納する。
// 今回のケースではスキーマ定義の並び順をそのまま使えるため、enum の値を配列として取り出すだけでよい。
const levelOrder = Object.values($Enums.Level);
// 並び順を調整したい場合は、任意の順番で配列をつくる。
// const levelOrder = [
// $Enums.Level.ADVANCED,
// $Enums.Level.INTERMEDIATE,
// $Enums.Level.ELEMENTARY,
// $Enums.Level.BEGINNER,
// ] as const;
return members.sort(
(a, b) => levelOrder.indexOf(a['level']) - levelOrder.indexOf(b['level']),
);
};