TypeScript SDK
リレーション
モデルのリレーションリソースの操作方法を学びます。
リレーションの定義はモデルの属性の定義方法と似ていますが、いくつかの違いがあります。以下の例を見てみましょう。
定義
// post.ts
import {Model} from "@tailflow/laravel-orion/lib/model";
import {BelongsTo} from "@tailflow/laravel-orion/lib/drivers/default/relations/belongsTo";
import {HasMany} from "@tailflow/laravel-orion/lib/drivers/default/relations/hasMany";
import {User} from "./user";
import {Comment} from "./comment";
export class Post extends Model<{
title: string,
body: string
}, {
thumbnail_url: string
}, {
user: User,
comments: Array<Comment>
}> {
public user(): BelongsTo<User> {
return new BelongsTo(User, this);
}
public comments(): HasMany<Comment> {
return new HasMany(Comment, this);
}
}
- モデル定義の3番目のジェネリックパラメータとして、リレーションとそのモデル型の一覧を指定します。
- 各プロパティ(リレーション)に対応するメソッドを作成し、リレーションタイプとモデルに応じたリレーションクエリビルダの新しいインスタンスを返します。
TypeScript SDKはすべてのリレーションタイプをサポートしています。
多対多
多対多リレーションを定義する際、中間(pivot)テーブルに追加のフィールドがある場合は、任意でpivotモデルの型を指定できます。
// post.ts
import {Model} from "@tailflow/laravel-orion/lib/model";
import {BelongsToMany} from "@tailflow/laravel-orion/lib/drivers/default/relations/belongsToMany";
import {Tag} from "./tag";
export class Post extends Model<{
title: string,
body: string
}, {
thumbnail_url: string
}, {
tags: Array<Tag>,
}> {
public tags(): BelongsToMany<Tag, {
pivot_field: string
}> {
return new BelongsToMany(Tag, this);
}
}
CRUDと検索
リレーションリソースに対するCRUDおよび検索操作は、モデルリソースに対する操作と基本的に同じです。
リレーションリソース専用のクエリビルダインスタンスを取得するには、モデルインスタンスでリレーションメソッドを呼び出します。
const post = Post.$query().find(5);
const comments = post.comments().get(); // ID が 5 の投稿のコメント一覧を取得します
const newComment = post.comments().store({body: 'Test comment'});
// など
1対多
リソースの関連付け(associate)
const post = Post.$query().find(5);
post.comments().associate(7);
リソースの関連付け解除(dissociate)
const post = Post.$query().find(5);
post.comments().dissociate(7);
多対多
リソースのアタッチ(attach)
const post = Post.$query().find(5);
post.tags().attach([2, 5, 7]);
// または
post.tags().attachWithFields({
2: {pivot_field: 'test value'},
5: {pivot_field: 'another value'},
7: {}
});
重複を許可したアタッチ
デフォルトでは、duplicatesクエリパラメータはfalseに設定されていますが、attachメソッドまたはattachWithFieldsメソッドの第2引数を指定することで、SDKにtrueを設定させることができます。
const post = Post.$query().find(5);
post.tags().attach([2, 5, 7], true);
リソースのデタッチ(detach)
const post = Post.$query().find(5);
post.tags().detach([2, 5, 7]);
// または
post.tags().detachWithFields({
2: {pivot_field: 'test value'},
5: {pivot_field: 'another value'},
7: {}
});
リソースの同期(sync)
const post = Post.$query().find(5);
post.tags().sync([2, 5, 7]);
// または
post.tags().syncWithFields({
2: {pivot_field: 'test value'},
5: {pivot_field: 'another value'},
7: {}
});
デタッチなしの同期
デフォルトでは、detachingクエリパラメータはtrueに設定されていますが、syncメソッドまたはsyncWithFieldsメソッドの第2引数を指定することで、SDKにfalseを設定させることができます。
const post = Post.$query().find(5);
post.tags().sync([2, 5, 7], false);
リソースのトグル(toggle)
const post = Post.$query().find(5);
post.tags().toggle([2, 5, 7]);
// または
post.tags().toggleWithFields({
2: {pivot_field: 'test value'},
5: {pivot_field: 'another value'},
7: {}
});
ピボットの更新
const post = Post.$query().find(5);
post.tags().updatePivot(2, {pivot_field: 'test value'});
post.tags().updatePivot(5, {pivot_field: 'test value'});
post.tags().updatePivot(7, {pivot_field: 'test value'});