ORM 钩子

未匹配的标注

挂钩是在预定义的生命周期事件期间你可以对模型实例执行的操作。使用钩子,你可以在模型中封装特定操作,而不是在代码库中的任何地方编写它们。

钩子的一个很好的例子是密码散列。你可以定义一个在save调用之前运行的挂钩,并将纯文本密码转换为哈希值。

// title: app/Models/User.ts
// 高亮开始
import Hash from '@ioc:Adonis/Core/Hash'
// 高亮结束
import { column, beforeSave, BaseModel } from '@ioc:Adonis/Lucid/Orm'

export default class User extends BaseModel {
  @column({ isPrimary: true })
  public id: number

  @column()
  public email: string

  @column()
  public password: string

  // 高亮开始
  @beforeSave()
  public static async hashPassword (user: User) {
    if (user.$dirty.password) {
      user.password = await Hash.make(user.password)
    }
  }
  // 高亮结束
}
  • beforeSave钩子在 INSERT 和 UPDATE 查询之前被调用。
  • 钩子可以是异步的。因此,你可以在其中使用await关键字。
  • 钩子总是被定义为静态函数,并接收模型的实例作为第一个参数。

了解$dirty属性

每次使用模型实例 created 或 updated 新用户时,都会调用beforeSave挂钩。

在更新期间,你可能更新了其他属性,但没有更新用户密码。因此不需要重新散列现有的散列,这就是使用$dirty对象的原因。

$dirty对象仅包含更改的值。因此,你可以检查密码是否已更改,然后对新值进行哈希处理。

可用的钩子

以下是所有可用钩子的列表。请务必阅读 decorators API 文档。

钩子 描述
beforeSave 在插入或更新查询之前调用,接收模型实例作为唯一参数
afterSave 在插入或更新查询之后调用。接收模型实例作为唯一参数
beforeCreate 仅在插入查询之前调用,接收模型实例作为唯一参数
afterCreate 仅在插入查询之后调用,接收模型实例作为唯一参数
beforeUpdate 仅在更新查询之前调用,接收模型实例作为唯一参数
afterUpdate 仅在更新查询之后调用,接收模型实例作为唯一参数
beforeDelete 在删除查询之前调用,接收模型实例作为唯一参数
afterDelete 在删除查询之后调用,接收模型实例作为唯一参数
beforePaginate 在分页查询之前调用,接收查询主构建器实例以及计数查询构建器实例
afterPaginate 在分页查询之后调用,接收查询主构建器实例以及计数查询构建器实例
beforeFetch 在 fetch 查询之前调用,接收查询生成器实例作为唯一参数
afterFetch 在 fetch 查询之后调用,接收模型实例数组
beforeFind 在 find 查询之前调用,接收查询生成器实例作为唯一参数
afterFind 在 find 查询之后调用。接收模型实例作为唯一参数

所有钩子都接收模型实例作为第一个参数,除了下面的:

beforeFind

beforeFind 钩子在执行查询以查找单行之前被调用,接收查询构建器实例,你可以将对其添加约束。

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

export default class User extends BaseModel {
  @beforeFind()
  public static ignoreDeleted (query: ModelQueryBuilderContract<typeof User>) {
    query.whereNull('is_deleted')
  }
}

afterFind

afterFind 事件接收模型实例。

import {
  BaseModel,
  afterFind,
} from '@ioc:Adonis/Lucid/Orm'

export default class User extends BaseModel {
  @afterFind()
  public static afterFindHook (user: User) {
  }
}

beforeFetch

与 beforeFind 类似,beforeFetch 钩子也接收查询构建器实例。但是,只要不使用 first 方法执行查询,就会调用此钩子。

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

export default class User extends BaseModel {
  @beforeFetch()
  public static ignoreDeleted (query: ModelQueryBuilderContract<typeof User>) {
    query.whereNull('is_deleted')
  }
}

afterFetch

afterFetch钩子接收模型实例数组。

import {
  BaseModel,
  afterFetch,
} from '@ioc:Adonis/Lucid/Orm'

export default class User extends BaseModel {
  @afterFetch()
  public static afterFetchHook (users: User[]) {
  }
}

beforePaginate

beforePaginate 查询在你使用 paginate 方法时执行。 paginate 方法同时触发 beforeFetch 和 beforePaginate 钩子。

钩子函数接收一组查询构建器。第一个实例用于计数查询,第二个实例用于主查询。

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

export default class User extends BaseModel {
  @beforePaginate()
  public static ignoreDeleted ([
    countQuery: ModelQueryBuilderContract<typeof User>,
    query: ModelQueryBuilderContract<typeof User>,
  ]) {
    query.whereNull('is_deleted')
    countQuery.whereNull('is_deleted')
  }
}

afterPaginate

afterPaginate 钩子接收 SimplePaginator 类的实例。paginate 方法会触发 afterFetch 和 afterPaginate 钩子。

import {
  BaseModel,
  afterPaginate,
} from '@ioc:Adonis/Lucid/Orm'

import {
  SimplePaginatorContract
} from '@ioc:Adonis/Lucid/Database'

export default class User extends BaseModel {
  @afterPaginate()
  public static afterPaginateHook (users: SimplePaginatorContract<User>) {
  }
}

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

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

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

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

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


暂无话题~