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

onUpdate

update / updateMany / updateManyAndReturn でレコードの PK(主キー)を変更する際、リレーション先のレコードをどう扱うかを定義します。

説明例用のシート

リレーション定義のシート例を使用します。

基本的な使い方

リレーション定義onUpdate を指定します。

const gassma = new Gassma.GassmaClient({
relations: {
Users: {
posts: {
type: "oneToMany",
to: "Posts",
field: "id",
reference: "authorId",
onUpdate: "Cascade",
},
},
},
});

アクションの種類

アクション動作
Cascade関連レコードの FK を新しい値に自動更新
SetNull関連レコードの FK を null にする
Restrict関連レコードが存在する場合、更新をエラーで阻止
NoAction何もしない(デフォルト)

Cascade

親レコードの PK を変更すると、関連する子レコードの FK が新しい値に自動的に更新されます。

const gassma = new Gassma.GassmaClient({
relations: {
Users: {
posts: {
type: "oneToMany",
to: "Posts",
field: "id",
reference: "authorId",
onUpdate: "Cascade",
},
},
},
});

// Alice の id を 1 → 10 に変更すると、Posts の authorId: 1 も authorId: 10 に更新される
gassma.Users.updateMany({
where: { name: "Alice" },
data: { id: 10 },
});

更新後の Posts シートは以下のようになります。

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

manyToMany の場合

manyToMany で Cascade を指定すると、中間テーブルの対応カラムが新しい値に更新されます。

relations: {
Posts: {
tags: {
type: "manyToMany",
to: "Tags",
field: "id",
reference: "id",
through: {
sheet: "PostTags",
field: "postId",
reference: "tagId",
},
onUpdate: "Cascade",
},
},
}

// 投稿の id を 1 → 100 に変更すると、PostTags の postId: 1 も postId: 100 に更新される
gassma.Posts.updateMany({
where: { id: 1 },
data: { id: 100 },
});

SetNull

親レコードの PK を変更すると、関連する子レコードの FK が null に更新されます。

const gassma = new Gassma.GassmaClient({
relations: {
Users: {
posts: {
type: "oneToMany",
to: "Posts",
field: "id",
reference: "authorId",
onUpdate: "SetNull",
},
},
},
});

// Alice の id を変更すると、Alice の投稿の authorId が null になる
gassma.Users.updateMany({
where: { name: "Alice" },
data: { id: 10 },
});

更新後の Posts シートは以下のようになります。

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

manyToMany で SetNull を指定した場合、何も行われません(中間テーブルの FK を null にしても意味がないため)。

Restrict

関連するレコードが 1 件でも存在する場合、更新を拒否してエラーをスローします。

const gassma = new Gassma.GassmaClient({
relations: {
Users: {
posts: {
type: "oneToMany",
to: "Posts",
field: "id",
reference: "authorId",
onUpdate: "Restrict",
},
},
},
});

// Alice は投稿を持っているため、id の変更はエラーになる
gassma.Users.updateMany({
where: { name: "Alice" },
data: { id: 10 },
});
// => RelationOnUpdateRestrictError

// Charlie は投稿を持たないため、正常に更新される
gassma.Users.updateMany({
where: { name: "Charlie" },
data: { id: 10 },
});
ヒント

Restrict のチェックは全てのリレーションに対して先に行われます。そのため、エラーが発生しても副作用(他のリレーションの Cascade 等)は実行されません。

NoAction

何も行いません。onUpdate を指定しない場合と同じ動作です。

relations: {
Users: {
posts: {
type: "oneToMany",
to: "Posts",
field: "id",
reference: "authorId",
onUpdate: "NoAction", // 指定しない場合と同じ
},
},
}

onDelete との組み合わせ

onDeleteonUpdate は同じリレーション定義に同時に指定できます。

relations: {
Users: {
posts: {
type: "oneToMany",
to: "Posts",
field: "id",
reference: "authorId",
onDelete: "Cascade", // 削除時: 投稿も一緒に削除
onUpdate: "Cascade", // PK更新時: 投稿の FK も更新
},
},
}