Skip to main content
Version: v6 - stable

关联范围

本节涉及关联范围,与 模型范围 类似但不相同。

¥This section concerns association scopes, which are similar but not the same as model scopes.

关联范围既可以放置在关联模型(关联的目标)上,也可以放置在多对多关系的直通表上。

¥Association scopes can be placed both on the associated model (the target of the association) and on the through table for Many-to-Many relationships.

概念

¥Concept

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

¥Similarly to how a model scope is automatically applied on the model static calls, such as Model.scope('foo').findAll(), an association scope is a rule (more precisely, a set of default attributes and options) that is automatically applied on instance calls from the model. Here, instance calls mean method calls that are called from an instance (rather than from the Model itself). Mixins are the main example of instance methods (instance.getSomething, instance.setSomething, instance.addSomething and instance.createSomething).

关联作用域的行为就像模型作用域一样,从某种意义上说,两者都会导致自动应用诸如 where 子句之类的查找器调用;区别在于,关联作用域不是应用于静态查找器调用(模型作用域就是这种情况),而是自动应用于实例查找器调用(例如 mixins)。

¥Association scopes behave just like model scopes, in the sense that both cause an automatic application of things like where clauses to finder calls; the difference being that instead of applying to static finder calls (which is the case for model scopes), the association scopes automatically apply to instance finder calls (such as mixins).

示例

¥Example

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

¥A basic example of an association scope for the One-to-Many association between models Foo and Bar is shown below.

  • 设置:

    ¥Setup:

    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:

    ¥After this setup, calling myFoo.getOpenBars() generates the following 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 子句中。

¥With this we can see that upon calling the .getOpenBars() mixin, the association scope { status: 'open' } was automatically applied into the WHERE clause of the generated SQL.

使用标准范围实现相同的行为

¥Achieving the same behavior with standard scopes

我们可以使用标准范围实现相同的行为:

¥We could have achieved the same behavior with standard scopes:

// 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。

¥With the above code, myFoo.getOpenBars() yields the same SQL shown above.