跳至主要内容
版本:v6 - 稳定版

关联作用域

本节涉及关联作用域,它与模型作用域相似但并不相同。

关联作用域既可以放置在关联模型(关联的目标)上,也可以放置在多对多关系的中间表上。

概念

类似于模型作用域如何在模型静态调用(例如 Model.scope('foo').findAll())上自动应用,关联作用域是一条规则(更准确地说,是一组默认属性和选项),它会在模型的实例调用上自动应用。这里,实例调用是指从实例(而不是从模型本身)调用的方法调用。Mixin 是实例方法的主要示例(instance.getSomethinginstance.setSomethinginstance.addSomethinginstance.createSomething)。

关联作用域的行为与模型作用域完全相同,因为两者都会导致自动应用 where 子句等内容到查找器调用;区别在于,模型作用域应用于静态查找器调用,而关联作用域自动应用于实例查找器调用(例如 Mixin)。

示例

下面显示了模型 FooBar 之间一对多关联的关联作用域的基本示例。

  • 设置

    const Foo = sequelize.define('foo', { name: DataTypes.STRING });
    const Bar = sequelize.define('bar', { status: DataTypes.STRING });
    Foo.hasMany(Bar, {
    scope: {
    status: 'open',
    },
    as: 'openBars',
    });
    await sequelize.sync();
    const myFoo = await Foo.create({ name: 'My Foo' });
  • 完成此设置后,调用 myFoo.getOpenBars() 会生成以下 SQL

    SELECT
    `id`, `status`, `createdAt`, `updatedAt`, `fooId`
    FROM `bars` AS `bar`
    WHERE `bar`.`status` = 'open' AND `bar`.`fooId` = 1;

由此可见,在调用 .getOpenBars() Mixin 时,关联作用域 { status: 'open' } 自动应用到生成的 SQL 的 WHERE 子句中。

使用标准作用域实现相同行为

我们可以使用标准作用域实现相同行为

// Foo.hasMany(Bar, {
// scope: {
// status: 'open'
// },
// as: 'openBars'
// });

Bar.addScope('open', {
where: {
status: 'open',
},
});
Foo.hasMany(Bar);
Foo.hasMany(Bar.scope('open'), { as: 'openBars' });

使用上述代码,myFoo.getOpenBars() 会产生与上面显示的相同的 SQL。