此系列文章的应用示例已发布于 GitHub: sequelize-docs-Zh-CN. 能够 Fork 帮助改进或 Star 关注更新. 欢迎 Star.html
本部分描述 sequelize 中的各类关联类型。 当调用 User.hasOne(Project)
这样的方法时,咱们说 User
模型(该函数被调用的模型)是 source 而 Project
模型(模型被传递为参数)是 target 。github
一对一关联是经过单个外键链接的两个模型之间的关联。sql
BelongsTo 关联是在 source model 上存在一对一关系的外键的关联。数据库
一个简单的例子是 Player 经过 player 的外键做为 Team 的一部分。segmentfault
const Player = this.sequelize.define('player', {/* attributes */}); const Team = this.sequelize.define('team', {/* attributes */}); Player.belongsTo(Team); // 将向 Team 添加一个 teamId 属性以保存 Team 的主键值
默认状况下,将从目标模型名称和目标主键名称生成 belongsTo 关系的外键。数组
默认的样式是 camelCase
,可是若是源模型配置为 underscored: true
,那么 foreignKey 将是snake_case
。安全
const User = this.sequelize.define('user', {/* attributes */}) const Company = this.sequelize.define('company', {/* attributes */}); User.belongsTo(Company); // 将 companyId 添加到 user const User = this.sequelize.define('user', {/* attributes */}, {underscored: true}) const Company = this.sequelize.define('company', { uuid: { type: Sequelize.UUID, primaryKey: true } }); User.belongsTo(Company); // 将 company_uuid 添加到 user
在已定义 as
的状况下,将使用它代替目标模型名称。ide
const User = this.sequelize.define('user', {/* attributes */}) const UserRole = this.sequelize.define('userRole', {/* attributes */}); User.belongsTo(UserRole, {as: 'role'}); // 将 role 添加到 user 而不是 userRole
在全部状况下,默认外键能够用 foreignKey
选项覆盖。
当使用外键选项时,Sequelize 将按原样使用:函数
const User = this.sequelize.define('user', {/* attributes */}) const Company = this.sequelize.define('company', {/* attributes */}); User.belongsTo(Company, {foreignKey: 'fk_company'}); // 将 fk_company 添加到 User
目标键是源模型上的外键列指向的目标模型上的列。 默认状况下,belongsTo 关系的目标键将是目标模型的主键。 要定义自定义列,请使用 targetKey
选项。
const User = this.sequelize.define('user', {/* attributes */}) const Company = this.sequelize.define('company', {/* attributes */}); User.belongsTo(Company, {foreignKey: 'fk_companyname', targetKey: 'name'}); // 添加 fk_companyname 到 User
HasOne 关联是在 target model 上存在一对一关系的外键的关联。
const User = sequelize.define('user', {/* ... */}) const Project = sequelize.define('project', {/* ... */}) // 单向关联 Project.hasOne(User) /* 在此示例中,hasOne 将向 User 模型添加一个 projectId 属性 ! 此外,Project.prototype 将根据传递给定义的第一个参数获取 getUser 和 setUser 的方法。 若是启用了 underscore 样式,则添加的属性将是 project_id 而不是 projectId。 外键将放在 users 表上。 你也能够定义外键,例如 若是您已经有一个现有的数据库而且想要处理它: */ Project.hasOne(User, { foreignKey: 'initiator_id' }) /* 由于Sequelize将使用模型的名称(define的第一个参数)做为访问器方法, 还能够将特殊选项传递给hasOne: */ Project.hasOne(User, { as: 'Initiator' }) // 如今你能够得到 Project#getInitiator 和 Project#setInitiator // 或者让咱们来定义一些本身的参考 const Person = sequelize.define('person', { /* ... */}) Person.hasOne(Person, {as: 'Father'}) // 这会将属性 FatherId 添加到 Person // also possible: Person.hasOne(Person, {as: 'Father', foreignKey: 'DadId'}) // 这将把属性 DadId 添加到 Person // 在这两种状况下,你均可以: Person#setFather Person#getFather // 若是你须要联结表两次,你能够联结同一张表 Team.hasOne(Game, {as: 'HomeTeam', foreignKey : 'homeTeamId'}); Team.hasOne(Game, {as: 'AwayTeam', foreignKey : 'awayTeamId'}); Game.belongsTo(Team);
即便它被称为 HasOne 关联,对于大多数1:1关系,您一般须要BelongsTo关联,由于 BelongsTo 将会在 hasOne 将添加到目标的源上添加 foreignKey。
在Sequelize 1:1关系中可使用HasOne和BelongsTo进行设置。 它们适用于不一样的场景。 让咱们用一个例子来研究这个差别。
假设咱们有两个表能够连接 Player 和 Team 。 让咱们定义他们的模型。
const Player = this.sequelize.define('player', {/* attributes */}) const Team = this.sequelize.define('team', {/* attributes */});
当咱们链接 Sequelize 中的两个模型时,咱们能够将它们称为一对 source 和 target 模型。像这样
将 Player 做为 source 而 Team 做为 target
Player.belongsTo(Team); //或 Player.hasOne(Team);
将 Team 做为 source 而 Player 做为 target
Team.belongsTo(Player); //Or Team.hasOne(Player);
HasOne 和 BelongsTo 将关联键插入到不一样的模型中。 HasOne 在 target 模型中插入关联键,而 BelongsTo 将关联键插入到 source 模型中。
下是一个示例,说明了 BelongsTo 和 HasOne 的用法。
const Player = this.sequelize.define('player', {/* attributes */}) const Coach = this.sequelize.define('coach', {/* attributes */}) const Team = this.sequelize.define('team', {/* attributes */});
假设咱们的 Player
模型有关于其团队的信息为 teamId
列。 关于每一个团队的 Coach
的信息做为 coachId
列存储在 Team
模型中。 这两种状况都须要不一样种类的1:1关系,由于外键关系每次出如今不一样的模型上。
当关于关联的信息存在于 source 模型中时,咱们可使用 belongsTo
。 在这种状况下,Player
适用于 belongsTo
,由于它具备 teamId
列。
Player.belongsTo(Team) // `teamId` 将被添加到 Player / Source 模型中
当关于关联的信息存在于 target 模型中时,咱们可使用 hasOne
。 在这种状况下, Coach
适用于 hasOne
,由于 Team
模型将其 Coach
的信息存储为 coachId
字段。
Coach.hasOne(Team) // `coachId` 将被添加到 Team / Target 模型中
一对多关联将一个来源与多个目标链接起来。 而多个目标接到同一个特定的源。
const User = sequelize.define('user', {/* ... */}) const Project = sequelize.define('project', {/* ... */}) // 好。 如今,事情变得更加复杂(对用户来讲并不真实可见)。 // 首先咱们来定义一个 hasMany 关联 Project.hasMany(User, {as: 'Workers'})
这将添加属性 projectId
或 project_id
到 User。 Project 的实例将得到访问器 getWorkers
和 setWorkers
。 咱们让它保持原样,让它成为单向关联。
可是咱们想要更多! 让咱们在下一节中以其余方式定义并建立一个多对多的关联:
有时您可能须要在不一样的列上关联记录,您可使用 sourceKey
选项:
const City = sequelize.define('city', { countryCode: Sequelize.STRING }); const Country = sequelize.define('country', { isoCode: Sequelize.STRING }); // 在这里,咱们能够根据国家代码链接国家和城市 Country.hasMany(City, {foreignKey: 'countryCode', sourceKey: 'isoCode'}); City.belongsTo(Country, {foreignKey: 'countryCode', targetKey: 'isoCode'});
多对多关联用于将源与多个目标相链接。 此外,目标也能够链接到多个源。
Project.belongsToMany(User, {through: 'UserProject'}); User.belongsToMany(Project, {through: 'UserProject'});
这将建立一个名为 UserProject 的新模型,具备等效的外键projectId
和userId
。 属性是否为camelcase
取决于由表(在这种状况下为User
和Project
)链接的两个模型。
定义 through
为 required。 Sequelize 之前会尝试自动生成名称,但并不老是致使最合乎逻辑的设置。
这将添加方法 getUsers
, setUsers
, addUser
,addUsers
到 Project
, 还有 getProjects
, setProjects
, addProject
, 和 addProjects
到 User
.
有时,您可能须要在关联中使用它们时重命名模型。 让咱们经过使用别名(as
)选项将 users 定义为 workers 而 projects 定义为t asks。 咱们还将手动定义要使用的外键:
User.belongsToMany(Project, { as: 'Tasks', through: 'worker_tasks', foreignKey: 'userId' }) Project.belongsToMany(User, { as: 'Workers', through: 'worker_tasks', foreignKey: 'projectId' })
foreignKey
将容许你在 through 关系中设置 source model 键。
otherKey
将容许你在 through 关系中设置 target model 键。
User.belongsToMany(Project, { as: 'Tasks', through: 'worker_tasks', foreignKey: 'userId', otherKey: 'projectId'})
固然你也可使用 belongsToMany 定义自我引用:
Person.belongsToMany(Person, { as: 'Children', through: 'PersonChildren' }) // 这将建立存储对象的 ID 的表 PersonChildren。
若是您想要链接表中的其余属性,则能够在定义关联以前为链接表定义一个模型,而后再说明它应该使用该模型进行链接,而不是建立一个新的关联:
const User = sequelize.define('user', {}) const Project = sequelize.define('project', {}) const UserProjects = sequelize.define('userProjects', { status: DataTypes.STRING }) User.belongsToMany(Project, { through: UserProjects }) Project.belongsToMany(User, { through: UserProjects })
要向 user 添加一个新 project 并设置其状态,您能够将额外的 options.through
传递给 setter,其中包含链接表的属性
user.addProject(project, { through: { status: 'started' }})
默认状况下,上面的代码会将 projectId 和 userId 添加到 UserProjects 表中, 删除任何先前定义的主键属性 - 表将由两个表的键的组合惟一标识,而且没有其余主键列。 要在 UserProjects
模型上强添加一个主键,您能够手动添加它。
const UserProjects = sequelize.define('userProjects', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, status: DataTypes.STRING })
使用多对多你能够基于 through 关系查询并选择特定属性。 例如经过 through 使用findAll
User.findAll({ include: [{ model: Project, through: { attributes: ['createdAt', 'startedAt', 'finishedAt'], where: {completed: true} } }] });
本节涉及关联做用域。 有关关联做用域与相关模型上的做用域的定义,请参阅 做用域。
关联做用域容许您在关联上放置一个做用域(一套 get
和 create
的默认属性)。做用域能够放在相关联的模型(关联的target)上,也能够经过表上的 n:m 关系。
假设咱们有表评论,帖子和图像。 一个评论能够经过 commentable_id
和 commentable
关联到一个图像或一个帖子 - 咱们说 Post 和 Image 是 Commentable
const Comment = this.sequelize.define('comment', { title: Sequelize.STRING, commentable: Sequelize.STRING, commentable_id: Sequelize.INTEGER }); Comment.prototype.getItem = function(options) { return this['get' + this.get('commentable').substr(0, 1).toUpperCase() + this.get('commentable').substr(1)](options); }; Post.hasMany(this.Comment, { foreignKey: 'commentable_id', constraints: false, scope: { commentable: 'post' } }); Comment.belongsTo(this.Post, { foreignKey: 'commentable_id', constraints: false, as: 'post' }); Image.hasMany(this.Comment, { foreignKey: 'commentable_id', constraints: false, scope: { commentable: 'image' } }); Comment.belongsTo(this.Image, { foreignKey: 'commentable_id', constraints: false, as: 'image' });
constraints: false,
禁用引用约束 - 因为 commentable_id
列引用了几个表,咱们不能添加一个 REFERENCES
约束。 请注意,Image - > Comment 和 Post - > Comment 关系分别定义了一个做用域:commentable: 'image'
和 commentable: 'post'
。 使用关联功能时自动应用此做用域:
image.getComments() SELECT * FROM comments WHERE commentable_id = 42 AND commentable = 'image'; image.createComment({ title: 'Awesome!' }) INSERT INTO comments (title, commentable_id, commentable) VALUES ('Awesome!', 42, 'image'); image.addComment(comment); UPDATE comments SET commentable_id = 42, commentable = 'image'
Comment
上的 getItem
做用函数完成了图片 - 它只是将commentable
字符串转换为getImage
或getPost
的一个调用,提供一个注释是属于一个帖子仍是一个图像的抽象概念。您能够将普通选项对象做为参数传递给 getItem(options)
,以指定任何条件或包含的位置。
继续多态模型的思路,考虑一个 tag 表 - 一个 item 能够有多个 tag,一个 tag 能够与多个 item 相关。
为了简洁起见,该示例仅显示了 Post 模型,但实际上 Tag 与其余几个模型相关。
const ItemTag = sequelize.define('item_tag', { id : { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, tag_id: { type: DataTypes.INTEGER, unique: 'item_tag_taggable' }, taggable: { type: DataTypes.STRING, unique: 'item_tag_taggable' }, taggable_id: { type: DataTypes.INTEGER, unique: 'item_tag_taggable', references: null } }); const Tag = sequelize.define('tag', { name: DataTypes.STRING }); Post.belongsToMany(Tag, { through: { model: ItemTag, unique: false, scope: { taggable: 'post' } }, foreignKey: 'taggable_id', constraints: false }); Tag.belongsToMany(Post, { through: { model: ItemTag, unique: false }, foreignKey: 'tag_id', constraints: false });
请注意,做用域列(taggable
)如今在 through 模型(ItemTag
)上。
咱们还能够定义一个更具限制性的关联,例如,经过应用through 模型(ItemTag
)和目标模型(Tag
)的做用域来获取全部挂起的 tag。
Post.hasMany(Tag, { through: { model: ItemTag, unique: false, scope: { taggable: 'post' } }, scope: { status: 'pending' }, as: 'pendingTags', foreignKey: 'taggable_id', constraints: false }); Post.getPendingTags();
SELECT `tag`.* INNER JOIN `item_tags` AS `item_tag` ON `tag`.`id` = `item_tag`.`tagId` AND `item_tag`.`taggable_id` = 42 AND `item_tag`.`taggable` = 'post' WHERE (`tag`.`status` = 'pending');
constraints: false
禁用 taggable_id
列上的引用约束。 由于列是多态的,咱们不能说它是 REFERENCES
一个特定的表。
默认状况下,Sequelize将使用模型名称(传递给sequelize.define
的名称),以便在关联时使用模型名称。 例如,一个名为user
的模型会将关联模型的实例中的get / set / add User
函数和加入一个名为.user
的属性,而一个名为User
的模型会添加相同的功能,和一个名为.User
的属性(注意大写U)。
正如咱们已经看到的,你可使用as
来关联模型。 在单个关联(has one 和 belongs to),别名应该是单数,而对于许多关联(has many)它应该是复数。 Sequelize而后使用[inflection] [0]库将别名转换为其单数形式。 可是,这可能并不老是适用于不规则或非英语单词。 在这种状况下,您能够提供复数和单数形式的别名:
User.belongsToMany(Project, { as: { singular: 'task', plural: 'tasks' }}) // Notice that inflection has no problem singularizing tasks, this is just for illustrative purposes.
若是你知道模型将始终在关联中使用相同的别名,则能够在建立模型时提供它
const Project = sequelize.define('project', attributes, { name: { singular: 'task', plural: 'tasks', } }) User.belongsToMany(Project);
这将为用户实例添加 add/set/get Tasks
方法。
记住,使用as
来更改关联的名称也会改变外键的名称。 当使用as
时,也能够指定外键是最安全的。
Invoice.belongsTo(Subscription) Subscription.hasMany(Invoice)
不使用 as
,这会按预期添加 subscriptionId
。 可是,若是您要发送Invoice.belongsTo(Subscription, { as: 'TheSubscription' })
,那么您将同时拥有 subscriptionId
和 theSubscriptionId
,由于 sequelize 不够聪明,没法肯定调用是相同关系的两面。 foreignKey
修正了这个问题;
Invoice.belongsTo(Subscription, , { as: 'TheSubscription', foreignKey: 'subscription_id' }) Subscription.hasMany(Invoice, { foreignKey: 'subscription_id' )
由于 Sequelize 作了不少神奇的事,因此你必须在设置关联后调用 Sequelize.sync
。 这样作将容许您进行如下操做:
Project.belongsToMany(Task) Task.belongsToMany(Project) Project.create()... Task.create()... Task.create()... // 保存它们.. 而后: project.setTasks([task1, task2]).then(() => { // 已保存! }) // 好的,如今它们已经保存了...我怎么才能获得他们? project.getTasks().then(associatedTasks => { // associatedTasks 是一个 tasks 的数组 }) // 您还能够将过滤器传递给getter方法。 // 它们与你能传递给常规查找器方法的选项相同。 project.getTasks({ where: 'id > 10' }).then(tasks => { // id大于10的任务 }) // 你也能够仅检索关联对象的某些字段。 project.getTasks({attributes: ['title']}).then(tasks => { // 使用属性“title”和“id”检索任务 })
要删除建立的关联,您能够调用set方法而不使用特定的ID:
// 删除与 task1 的关联 project.setTasks([task2]).then(associatedTasks => { // 你将只获得 task2 }) // 删除所有 project.setTasks([]).then(associatedTasks => { // 你将获得空数组 }) // 或更直接地删除 project.removeTask(task1).then(() => { // 什么都没有 }) // 而后再次添加它们 project.addTask(task1).then(function() { // 它们又回来了 })
反之亦然你固然也能够这样作:
// project与task1和task2相关联 task2.setProject(null).then(function() { // 什么都没有 })
对于 hasOne/belongsTo 与其基本相同:
Task.hasOne(User, {as: "Author"}) Task#setAuthor(anAuthor)
能够经过两种方式添加与自定义链接表的关系的关联(继续前一章中定义的关联):
// 在建立关联以前,经过向对象添加具备链接表模型名称的属性 project.UserProjects = { status: 'active' } u.addProject(project) // 或者在添加关联时提供第二个options.through参数,其中包含应该在链接表中的数据 u.addProject(project, { through: { status: 'active' }}) // 关联多个对象时,能够组合上述两个选项。 在这种状况下第二个参数 // 若是没有提供使用的数据将被视为默认对象 project1.UserProjects = { status: 'inactive' } u.setProjects([project1, project2], { through: { status: 'active' }}) // 上述代码将对项目1记录无效,而且在链接表中对项目2进行active
当获取具备自定义链接表的关联的数据时,链接表中的数据将做为DAO实例返回:
u.getProjects().then(projects => { const project = projects[0] if (project.UserProjects.status === 'active') { // .. 作点什么 // 因为这是一个真正的DAO实例,您能够在完成操做以后直接保存它 return project.UserProjects.save() } })
若是您仅须要链接表中的某些属性,则能够提供具备所需属性的数组:
// 这将仅从 Projects 表中选择 name,仅从 UserProjects 表中选择status user.getProjects({ attributes: ['name'], joinTableAttributes: ['status']})
您还能够检查对象是否已经与另外一个对象相关联(仅 n:m)。 这是你怎么作的
// 检查对象是不是关联对象之一: Project.create({ /* */ }).then(project => { return User.create({ /* */ }).then(user => { return project.hasUser(user).then(result => { // 结果是 false return project.addUser(user).then(() => { return project.hasUser(user).then(result => { // 结果是 true }) }) }) }) }) // 检查全部关联的对象是否如预期的那样: // 咱们假设咱们已经有一个项目和两个用户 project.setUsers([user1, user2]).then(() => { return project.hasUsers([user1]); }).then(result => { // 结果是 false return project.hasUsers([user1, user2]); }).then(result => { // 结果是 true })
当您在sequelize模型中建立关联时,将自动建立具备约束的外键引用。 设置以下:
const Task = this.sequelize.define('task', { title: Sequelize.STRING }) const User = this.sequelize.define('user', { username: Sequelize.STRING }) User.hasMany(Task) Task.belongsTo(User)
将生成如下SQL:
CREATE TABLE IF NOT EXISTS `User` ( `id` INTEGER PRIMARY KEY, `username` VARCHAR(255) ); CREATE TABLE IF NOT EXISTS `Task` ( `id` INTEGER PRIMARY KEY, `title` VARCHAR(255), `user_id` INTEGER REFERENCES `User` (`id`) ON DELETE SET NULL ON UPDATE CASCADE );
在task和user的关系之 中在task上注入user_id
外键,并将其标记为User
表的引用。默认状况下,若是引用的用户被删除,user_id
将被设置为NULL
,若是更新了用户标识的id,则会被更新。经过将onUpdate
和onDelete
选项传递给关联调用,能够覆盖这些选项。验证选项为RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL
。
对于1:1和1:m关联,默认选项为SET NULL
用于删除, CASCADE
用于更新。对于n:m,二者的默认值为CASCADE
。这意味着,若是从n:m关联的一侧删除或更新行,引用该行的链接表中的全部行也将被删除或更新。
在表之间添加约束意味着在使用sequelize.sync
时,必须以特定顺序在数据库中建立表。若是Task
引用了User
,则必须先建立User
表,而后才能建立Task
表。这有时可能致使循环引用,其中后遗症找不到要同步的顺序。想象一下文件和版本的场景。一个文档能够有多个版本,为方便起见,一个文档能够引用它的当前版本。
const Document = this.sequelize.define('document', { author: Sequelize.STRING }) const Version = this.sequelize.define('version', { timestamp: Sequelize.DATE }) Document.hasMany(Version) // 这将 document_id 添加到版本 Document.belongsTo(Version, { as: 'Current', foreignKey: 'current_version_id'}) // 这将current_version_id添加到文档
可是,上面的代码将致使如下错误: Cyclic dependency found. 'Document' is dependent of itself. Dependency Chain: Document -> Version => Document
.
为了减轻这一点,咱们能够将 constraints: false
传递给其中一个关联:
Document.hasMany(Version) Document.belongsTo(Version, { as: 'Current', foreignKey: 'current_version_id', constraints: false})
这将容许咱们正确地同步表:
CREATE TABLE IF NOT EXISTS `Document` ( `id` INTEGER PRIMARY KEY, `author` VARCHAR(255), `current_version_id` INTEGER ); CREATE TABLE IF NOT EXISTS `Version` ( `id` INTEGER PRIMARY KEY, `timestamp` DATETIME, `document_id` INTEGER REFERENCES `Document` (`id`) ON DELETE SET NULL ON UPDATE CASCADE );
有时,您可能须要引用另外一个表,而不添加任何约束或关联。 在这种状况下,您能够手动将引用属性添加到模式定义,并标记它们之间的关系。
// 在咱们调用 Trainer.hasMany(series) 以后 Series 有一个 外参考键 trainer_id=Trainer.id const Series = sequelize.define('series', { title: DataTypes.STRING, sub_title: DataTypes.STRING, description: DataTypes.TEXT, // 用 `Trainer` 设置外键关系(hasMany) trainer_id: { type: DataTypes.INTEGER, references: { model: "trainers", key: "id" } } }) const Trainer = sequelize.define('trainer', { first_name: DataTypes.STRING, last_name: DataTypes.STRING }); // 在咱们调用 Series.hasOne(Video) 以后 Video 有一个 外参考键 series_id=Series.id const Video = sequelize.define('video', { title: DataTypes.STRING, sequence: DataTypes.INTEGER, description: DataTypes.TEXT, // 用 `Series` 设置关系(hasOne) series_id: { type: DataTypes.INTEGER, references: { model: Series, // 能够是表示表名称的字符串,也能够是对模型的引用 key: "id" } } }); Series.hasOne(Video); Trainer.hasMany(Series);
若是全部元素都是新的,则能够在一个步骤中建立具备嵌套关联的实例。
考虑如下模型:
const Product = this.sequelize.define('product', { title: Sequelize.STRING }); const User = this.sequelize.define('user', { first_name: Sequelize.STRING, last_name: Sequelize.STRING }); const Address = this.sequelize.define('address', { type: Sequelize.STRING, line_1: Sequelize.STRING, line_2: Sequelize.STRING, city: Sequelize.STRING, state: Sequelize.STRING, zip: Sequelize.STRING, }); Product.User = Product.belongsTo(User); User.Addresses = User.hasMany(Address); // 也能用于 `hasOne`
能够经过如下方式在一个步骤中建立一个新的Product
, User
和一个或多个Address
:
return Product.create({ title: 'Chair', user: { first_name: 'Mick', last_name: 'Broadstone', addresses: [{ type: 'home', line_1: '100 Main St.', city: 'Austin', state: 'TX', zip: '78704' }] } }, { include: [{ association: Product.User, include: [ User.Addresses ] }] });
这里,咱们的用户模型称为user
,带小写u - 这意味着对象中的属性也应该是user
。 若是给sequelize.define
指定的名称为User
,对象中的键也应为User
。 对于addresses
也是一样的,除了它是一个 hasMany
关联的复数。
能够将前面的示例扩展为支持关联别名。
const Creator = Product.belongsTo(User, {as: 'creator'}); return Product.create({ title: 'Chair', creator: { first_name: 'Matt', last_name: 'Hansen' } }, { include: [ Creator ] });
咱们来介绍将产品与许多标签相关联的功能。 设置模型可能以下所示:
const Tag = this.sequelize.define('tag', { name: Sequelize.STRING }); Product.hasMany(Tag); // Also works for `belongsToMany`.
如今,咱们能够经过如下方式建立具备多个标签的产品:
Product.create({ id: 1, title: 'Chair', tags: [ { name: 'Alpha'}, { name: 'Beta'} ] }, { include: [ Tag ] })
而后,咱们能够修改此示例以支持别名:
const Categories = Product.hasMany(Tag, {as: 'categories'}); Product.create({ id: 1, title: 'Chair', categories: [ {id: 1, name: 'Alpha'}, {id: 2, name: 'Beta'} ] }, { include: [{ model: Categories, as: 'categories' }] })
若是这篇文章对您有帮助, 感谢 下方点赞 或 Star GitHub: sequelize-docs-Zh-CN 支持, 谢谢.