メインコンテンツまでスキップ

リレーション定義

複数のシート間のリレーション(関連)を定義することで、include によるリレーション先データの取得や、where でのリレーション条件フィルタが可能になります。

説明例用のシート

以降のリレーションドキュメントでは、以下のシートを例として使用します。

Users シート

idnameemail
1Alice[email protected]
2Bob[email protected]
3Charlie[email protected]

Posts シート

idtitleauthorIdpublished
1初めての投稿1true
2GAS の使い方1true
3下書き記事2false

Profiles シート

iduserIdbio
11エンジニアです
22デザイナーです

Tags シート

idname
1GAS
2JavaScript

PostTags シート(中間テーブル)

postIdtagId
11
12
21

基本的な定義方法

GassmaClient のコンストラクタに relations オプションを渡すことで、シート間のリレーションを定義できます。

const gassma = new Gassma.GassmaClient({
relations: {
// シート名(スプレッドシート上の実際のシート名と一致させる)
Users: {
// リレーション名(自由な名前を付けられます。include や where で使用するキー名になります)
posts: {
type: "oneToMany",
to: "Posts",
field: "id",
reference: "authorId",
},
},
},
});

スプレッドシート ID を指定する場合は id も一緒に渡します。

const gassma = new Gassma.GassmaClient({
id: "XXXXXXXXXXXXXXXXXXX",
relations: {
// ...
},
});

リレーション定義のキー

キー名内容省略備考
typeリレーションの種類不可oneToMany / oneToOne / manyToOne / manyToMany
to関連先のシート名不可
field自シート側のカラム名不可FK または PK
reference関連先シート側のカラム名不可
through中間テーブルの設定manyToMany の場合は必須
onDelete削除時のアクションCascade / SetNull / Restrict / NoAction
onUpdatePK 更新時のアクションCascade / SetNull / Restrict / NoAction

リレーションの種類

oneToMany(1 対 多)

1 つの親レコードに対して、複数の子レコードが紐づく関係です。

例:1 人のユーザーが複数の投稿を持つ

relations: {
Users: {
posts: {
type: "oneToMany",
to: "Posts",
field: "id", // Users の PK
reference: "authorId", // Posts の FK
},
},
}

include で取得すると配列が返ります。

manyToOne(多 対 1)

oneToMany の逆方向です。子レコードから親レコードへの参照を定義します。

例:投稿から著者(ユーザー)を取得

relations: {
Posts: {
author: {
type: "manyToOne",
to: "Users",
field: "authorId", // Posts の FK
reference: "id", // Users の PK
},
},
}

include で取得すると単一オブジェクトまたは null が返ります。

manyToOneFK を保有する側(Prisma スキーマで @relation(fields: ...) を書く側)の定義です。1 対 1 の関係であっても、FK を保有する側は manyToOne と定義します。

oneToOne(1 対 1)

1 つのレコードに対して、1 つだけ紐づくレコードがある関係です。oneToOne は 1 対 1 のうち FK を持たない側専用の定義です。

例:ユーザーとプロフィール(FK の userId を持つのは Profiles 側)

relations: {
Users: {
profile: {
type: "oneToOne",
to: "Profiles",
field: "id", // Users の PK
reference: "userId", // Profiles の FK
},
},
}

include で取得すると単一オブジェクトまたは null が返ります。同じ reference 値を持つレコードが複数存在する場合はエラーとなります。

注記

FK を保有する側(上の例では Profiles)から逆方向のリレーションを定義する場合は、1 対 1 であっても manyToOne を使用します。

relations: {
Profiles: {
user: {
type: "manyToOne",
to: "Users",
field: "userId", // Profiles の FK
reference: "id", // Users の PK
},
},
}

manyToMany(多 対 多)

中間テーブルを経由して、多対多の関係を定義します。

例:投稿とタグ

relations: {
Posts: {
tags: {
type: "manyToMany",
to: "Tags",
field: "id", // Posts の PK
reference: "id", // Tags の PK
through: {
sheet: "PostTags", // 中間テーブルのシート名
field: "postId", // 中間テーブルにおける Posts 側の FK
reference: "tagId", // 中間テーブルにおける Tags 側の FK
},
},
},
}

include で取得すると配列が返ります。

複数リレーションの定義

1 つのシートに複数のリレーションを定義できます。また、複数シートにまたがって定義することもできます。

const gassma = new Gassma.GassmaClient({
relations: {
Users: {
posts: {
type: "oneToMany",
to: "Posts",
field: "id",
reference: "authorId",
},
profile: {
type: "oneToOne",
to: "Profiles",
field: "id",
reference: "userId",
},
},
Posts: {
author: {
type: "manyToOne",
to: "Users",
field: "authorId",
reference: "id",
},
tags: {
type: "manyToMany",
to: "Tags",
field: "id",
reference: "id",
through: {
sheet: "PostTags",
field: "postId",
reference: "tagId",
},
},
},
},
});

バリデーション

リレーション定義に誤りがある場合、GassmaClient のインスタンス生成時にエラーがスローされます。

エラー原因
RelationSheetNotFoundErrorrelations のキー、tothrough.sheet に指定したシート名が存在しない
RelationMissingPropertyErrortype / to / field / reference が欠けている。manyToMany で through が欠けている
RelationInvalidPropertyTypeErrorプロパティの型が string でない
RelationInvalidTypeErrortype が 4 種類のいずれでもない
RelationInvalidOnDeleteErroronDelete が 4 種類のいずれでもない
RelationInvalidOnUpdateErroronUpdate が 4 種類のいずれでもない
RelationColumnNotFoundErrorfield / reference に指定したカラムがシート上に存在しない