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. 在模型定义中提供第三个泛型参数,列出各个关联及其模型类型。
  2. 为每个属性(关联)创建一个方法,并返回与该关联类型和模型对应的关联查询构建器的新实例。

TypeScript SDK 支持所有关联类型。

多对多

定义多对多关联时,如果中间表包含额外字段,你可以选择性地提供中间表模型类型。

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

一对多

关联资源

const post = Post.$query().find(5);

post.comments().associate(7);

解除关联资源

const post = Post.$query().find(5);

post.comments().dissociate(7);

多对多

附加资源

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,但你可以通过向 attachattachWithFields 方法提供第二个参数,让 SDK 将其设置为 true

const post = Post.$query().find(5);

post.tags().attach([2, 5, 7], true);

分离资源

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: {}
});

同步资源

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,但你可以通过向 syncsyncWithFields 方法提供第二个参数,让 SDK 将其设置为 false

const post = Post.$query().find(5);

post.tags().sync([2, 5, 7], false);

切换资源

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