Create a class that extends BaseModelFilter. The filter logic is driven by the keys provided in the input object (e.g., from request.qs()).
Key Concepts:
- Method Mapping: Input keys are mapped to methods in the class. For example, an input key
companyId will call the company(id: number) method. $query: Access the Lucid QueryBuilder via this.$query.$input: Access the full input object via this.$input.setup(): A method called on every filter execution. Use it for mandatory filters (e.g., this.$query.where('is_active', true)).- Empty Strings: Input values that are empty strings are automatically ignored.
_id Suffix: If static dropId = true is set, user_id in the input will call the user() method.camelCase: If static camelCase = true is set, mobile_phone or mobilePhone will both call the mobilePhone() method.
import { BaseModelFilter } from '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']
static dropId: boolean = true
static camelCase: boolean = true
// Filters 'companyId', 'company_id', or 'company'
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', `%${name}%`)
})
}
mobilePhone(phone: string) {
this.$query.where('mobile_phone', 'LIKE', `${phone}%`)
}
secretMethod(secretParameter: any) {
this.$query.where('some_column', true)
}
}