Sequelize
  • Introduction
  • 写在前面的话
  • 第一章 搭建环境
  • 第二章 模型定义
    • 2.1 实例变量方法
    • 2.2 定义一个模型
    • 2.3 模型字段类型
    • 2.3 导入与配置
  • 第三章 模型关系
    • 3.1 属于
    • 3.2 包含
    • 3.3 一对多
    • 3.4 多对多
    • 3.5 多态一对多
    • 3.6 多态多对多
    • 3.7 关系嵌套
  • 第四章 模型查询
  • 第五章 查询范围 Scope (预定义查询条件)
  • 第六章 生命周期函数 Hook
  • 第七章 数据库迁移 Migrate
  • 第八章 根据 Table 生成 Model
Powered by GitBook
On this page
  • Book 与 User 的 belongs 关系
  • 1. 保存关系
  • 2.添加代码提示
  • User 与 Tag 的 belongsToMany
  • 1.保存关系
  • 2.代码提示
  • 验证
  1. 第三章 模型关系

3.7 关系嵌套

在之前,创建一个有依赖其他模型的模型的时候,我们需要提前把依赖的模型给建立好,这样就非常麻烦,是不是有那么一种方法,在一个 create 里面把其他的依赖模型一起新建出来呢?

这一小节就来解决这个问题。这其中有一个坑(关于命名),让我调试的头皮发麻。

Book 与 User 的 belongs 关系

1. 保存关系

来到 book.ts , 首先保存一下 this.belongsTo 的返回值,在 d.ts 中的定义中写的返回的 void,其实并不是你可以log 一下,是一个包含 source target option 的对象。

(Book as any).associate = function(this: typeof Book, models: any){
   (Book as any).User = this.belongsTo(models.User);
}

2.添加代码提示

export interface BookAttributes {
  status: "inSale" | "noSale";
  description: string;
  title: string;
  author: string;

  User?: UserAttributes | Sequelize.BelongsToGetAssociationMixin<UserInstance>;
}

特别注意这里是 User,为什么是 User? 因为这个值要跟你 define 传入的第一个参数保持一致。 笔者一直认为是小写,自己写了很多例子验证就是没有正常运行,花了2天时间去找到这个问题。

这里的 User 跟实例的 User 重名了所有我们要用一个联合类型来保持父类接口的兼容性。

User 与 Tag 的 belongsToMany

belongsToMany、hasMany、hasOne 都是这样使用的。

1.保存关系

来到 user.ts

(User as any).associate = function(this: typeof User,models){
   // this.hasOne(models.Book);
   (User as any).Book = this.hasMany(models.Book);
   (User as any).Tag = this.belongsToMany(models.Tag, { through: 'user_tag'});
}

注意,这里的 this.hasMany 跟之前的第一个没有任何关系,因为此时的主体是 User,这是为了让 User.create 可以新建 Book 对象。

即:(实验请根据后面内容自行加上代码提示)

User.create({
    .....,
    Book: {
        .....,
    }
}, { include: [User.Book] })

2.代码提示

export interface UserAttributes {
  email: string;
  name: string;
  Tags?: TagAttributes[];
}

在 Tag 模型里面的define函数的第一个参数是 Tag,所以这里是 Tags,因为是多的一方,所以这里数组,并且与实例属性没有冲突,所以就不需要再做什么其他的。

验证

index.ts

await Book.create({
 author: '213',
 description: '213',
 status: "inSale",
 title: '12322',
 User: {
   email: '1733996866@qq.com',
   name: 'some',
   Tags: [
     {name: '123'},
     {name: '22'}
   ]
 }
},{
 include: [{
   association: (Book as any).User,
   include: [(User as any).Tag]
 }]
});

运行之后便可看到数据库中有数据,记得同步数据库表哦。

假如只有一项相关联的,这样写即可。假如是嵌套,像上面这样写即可,可以一直嵌套。

include: [(User as any).Tag]
Previous3.6 多态多对多Next第四章 模型查询

Last updated 7 years ago