Query Scopes

未匹配的标注

查询域 (query scopes) 是应用于查询构建器实例以修改查询的可重用函数。

有些方法被定义为模型类的静态属性,并接收当前查询作为第一个参数。例如:

// 文件名: app/Models/Post.ts
import { DateTime } from 'luxon'

import {
  BaseModel,
  column,
  scope // 👈 导入域方法
} from '@ioc:Adonis/Lucid/Orm'

export default class Post extends BaseModel {
  public static published = scope((query) => {
    query.where('publishedOn', '<=', DateTime.utc().toSQLDate())
  })
}

你可以使用 withScopes 方法在查询上应用 published 域。它接受一个回调,并让你可以访问所有作为方法的域。

Post
  .query()
  .withScopes((scopes) => scopes.published())

将参数传递给作用域

查询域也可以接受参数。例如:创建一个接受用户对象的域来确定他们可以查看的项目的范围。

import { DateTime } from 'luxon'
import User from 'App/Models/User'
import { BaseModel, column, scope } from '@ioc:Adonis/Lucid/Orm'

export default class Project extends BaseModel {

  public static visibleTo = scope((query, user: User) => {
    if (user.isAdmin) {
      return
    }

    /**
     * 非管理员用户只能查看自己团队的项目
     */
    query.where('teamId', user.teamId)
  })

}

现在,你可以调用 scopes.visibleTo 方法并将所需的参数传递给它。

Project
  .query()
  .withScopes((scopes) => scopes.visibleTo(auth.user))

在作用域内调用作用域

由于 scope 方法接收 Model query builder 的实例,因此你还可以在范围回调中引用其他模型域。例如:

import {
  scope,
  column,
  BaseModel,
  ModelQueryBuilderContract,
} from '@ioc:Adonis/Lucid/Orm'

type Builder = ModelQueryBuilderContract<typeof Post>

export default class Post extends BaseModel {
  public static firstScope = scope((query: Builder) => {
    query.withScopes((scopes) => scopes.secondScope())
  })

  public static secondScope = scope((query) => {
    query.whereNull('deletedAt')
  })
}

注意到我们上面创建的 Builder 类型了吗?

scope 方法不知道它在内部使用的模型(TypeScript 限制),因此它也无法推断模型的查询构建器类型。因此,我们需要输入提示 builder 属性,如下所示:

type Builder = ModelQueryBuilderContract<typeof Post>

public static firstScope = scope(
  (query: Builder) => {
  }
)

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/adonisjs/5.x/mo...

译文地址:https://learnku.com/docs/adonisjs/5.x/mo...

上一篇 下一篇
贡献者:1
讨论数量: 0
发起讨论 只看当前版本


暂无话题~