@ dirupt/adonis-lucid-filter (英语)
叉子为 adonis-lucid-过滤器 拥有 AdonisJS v7 支持
这个加通增加了过滤Lucid Models的功能.
贷项
这个包是叉子 adonis-lucid-filter 以 寻找Lab,更新为 AdonisJS v7 兼容性。 原执行的功劳全部归原作者.
版本数
| @ dirupt/adonis-lucid-filter (英语) | @ adonisjs/ lucid (英语) | 阿多尼斯·贾克 |
|---|---|---|
| ^6. *. * 翻译: | ^22.* (中文(简体) ) | ưμ㼯a |
对于 AdonisJS v6 ,使用原始软件包: adonis-lucid-filter@^5
从 adonis-lucid-filter
如果你是从上游来的 adonis-lucid-filter 软件包,迁移是直接的:
pnpm remove adonis-lucid-filter
pnpm add @dirupt/adonis-lucid-filter
然后更新代码库的进口:
- import { BaseModelFilter, Filterable } from 'adonis-lucid-filter'
+ import { BaseModelFilter, Filterable } from '@dirupt/adonis-lucid-filter'
并更新你的 adonisrc.ts数字 :
providers: [
- () => import('adonis-lucid-filter/provider'),
+ () => import('@dirupt/adonis-lucid-filter/provider'),
],
commands: [
- () => import('adonis-lucid-filter/commands')
+ () => import('@dirupt/adonis-lucid-filter/commands')
]
不同时安装两个软件包, 它们会扩展相同的
ModelQueryBuilder并且会发生冲突.
导言
示例,我们希望返回一个被多个参数过滤的用户列表. 当我们导航到:
/users?name=Tony&lastName=&companyId=2&industry=5
request.all() 或者说 request.qs() 将返回 :
{
"name": "Tony",
"lastName": "",
"companyId": 2,
"industry": 5
}
为了过滤所有这些参数,我们需要做一些诸如:
import type { HttpContext } from '@adonisjs/core/http'
import User from '#models/user'
export default class UsersController {
async index({ request }: HttpContext): Promise<User[]> {
const { companyId, lastName, name, industry } = request.qs()
const query = User.query().where('company_id', +companyId)
if (lastName) {
query.where('last_name', 'LIKE', `%${lastName}%`)
}
if (name) {
query.where(function () {
this.where('first_name', 'LIKE', `%${name}%`)
.orWhere('last_name', 'LIKE', `%${name}%`)
})
}
return query.exec()
}
}
要用 Lucid 过滤器过滤同样的输入 :
import type { HttpContext } from '@adonisjs/core/http'
import User from '#models/user'
export default class UsersController {
async index({ request }: HttpContext): Promise<User[]> {
return User.filter(request.qs()).exec()
}
}
安装
需要节点.js 24+和类型脚本
strict: true对于过滤器输入的完整类型推论.
pnpm add @dirupt/adonis-lucid-filter
安装后调用 configure数字 :
node ace configure @dirupt/adonis-lucid-filter
使用量
请在内部注册提供者和命令 adonisrc.ts 文档.
providers: [
// ...
() => import('@dirupt/adonis-lucid-filter/provider'),
],
commands: [
// ...
() => import('@dirupt/adonis-lucid-filter/commands')
]
生成过滤器
您可以使用以下 A 命令创建模型过滤器:
node ace make:filter user
何处 user 您正在创建过滤器的 Lucid 模型 。 这将创建 app/models/filters/user_filter.ts
定义过滤逻辑
根据骆驼大小写输入键传递到 filter() 方法.
- 空字符串被忽略
setup()将调用,不论输入_id从输入的末尾删除以定义方法这样过滤user_id将使用user()方法- 没有相应过滤方法的输入被忽略
- 键的值注入到方法中
- 所有值都可通过
this.$input属性 - 所有查询构建方法都可以在
this.$query在模型过滤类中的对象.
确定下列输入的方法:
{
"companyId": 5,
"name": "Tony",
"mobilePhone": "888555"
}
您将使用下列方法:
import { BaseModelFilter } from '@dirupt/adonis-lucid-filter'
import type { ModelQueryBuilderContract } from '@adonisjs/lucid/types/model'
import User from '#models/user'
export default class UserFilter extends BaseModelFilter {
declare $query: ModelQueryBuilderContract<typeof User>
static blacklist: string[] = ['secretMethod']
company(id: number) {
this.$query.where('company_id', id)
}
name(name: string) {
this.$query.where((builder) => {
builder
.where('first_name', 'LIKE', `%${name}%`)
.orWhere('last_name', 'LIKE', `%${name}%`)
})
}
mobilePhone(phone: string) {
this.$query.where('mobile_phone', 'LIKE', `${phone}%`)
}
secretMethod(secretParameter: any) {
this.$query.where('some_column', true)
}
}
黑名单
表格中定义的任何方法 blacklist 数组将不会被过滤器调用 。 这些方法通常用于内部过滤逻辑.
这个 whitelistMethod() 方法可用于动态白名单方法.
示例
setup($query) {
this.whitelistMethod('secretMethod')
this.$query.where('is_admin', true)
}
setup()可能不会同步
静态属性
export default class UserFilter extends BaseModelFilter {
// Blacklisted methods
static blacklist: string[] = []
// Dropped `_id` from the end of the input
static dropId: boolean = true
// Convert input keys to camelCase method names
static camelCase: boolean = true
}
将过滤器应用到模型
import UserFilter from '#models/filters/user_filter'
import { compose } from '@adonisjs/core/helpers'
import { Filterable } from '@dirupt/adonis-lucid-filter'
export default class User extends compose(BaseModel, Filterable) {
static $filter = () => UserFilter
// ...columns and props
}
这让你可以访问 filter() 接受输入对象的方法 :
import type { HttpContext } from '@adonisjs/core/http'
import User from '#models/user'
export default class UsersController {
async index({ request }: HttpContext): Promise<User[]> {
return User.filter(request.qs()).exec()
}
// or with paginate method
async index({ request }: HttpContext): Promise<ModelPaginatorContract<User>> {
const { page = 1, ...input } = request.qs()
return User.filter(input).paginate(page, 15)
}
}
动态过滤器
您可以通过传递过滤器来动态地定义过滤器,以作为过滤器()方法的第二个参数.
import type { HttpContext } from '@adonisjs/core/http'
import AdminFilter from '#models/filters/admin_filter'
import UserFilter from '#models/filters/user_filter'
export default class UsersController {
async index({ request, auth }: HttpContext): Promise<User[]> {
const filter = auth.user.isAdmin() ? AdminFilter : UserFilter
return User.filter(request.qs(), filter).exec()
}
}
过滤关系
用于过滤您可能使用的模型关系 .query().filter() 范围 filtration数字 :
import type { HttpContext } from '@adonisjs/core/http'
import User from '#models/user'
export default class UserPostsController {
async index({ params, request }: HttpContext): Promise<Post[]> {
const user: User = await User.findOrFail(params.user_id)
return user.related('posts').query()
.apply(scopes => scopes.filtration(request.qs()))
.exec()
// or
return user.related('posts').query().filter(request.qs()).exec()
}
}
关系模型必须有
Filterable混合和$filter必须定义
类型安全输入
包会暴露一个 InputObject<> 帮助推断直接从过滤类接受输入密钥 。 两者 snake_case, (中文(简体) ), camelCase 财务报告和审定财务报表 _id 可识别的变体:
import type { InputObject } from '@dirupt/adonis-lucid-filter/types/filter'
import type UserFilter from '#models/filters/user_filter'
type UserFilterInput = InputObject<UserFilter>
// → { company?: number; companyId?: number; company_id?: number;
// name?: string; mobilePhone?: string; mobile_phone?: string; ... }
// Useful to type request payloads or DTOs:
async index({ request }: HttpContext) {
const input = request.qs() as UserFilterInput
return User.filter(input).exec()
}
您的 IDE 将根据您所声明的方法自动完成合法密钥 UserFilter。 。 。 .