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);
    }
}
  1. モデル定義の3番目のジェネリックパラメータとして、リレーションとそのモデル型の一覧を指定します。
  2. 各プロパティ(リレーション)に対応するメソッドを作成し、リレーションタイプとモデルに応じたリレーションクエリビルダの新しいインスタンスを返します。

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'});