Uma biblioteca útil para fazer filtros para o Eloquent.
Esta biblioteca é útil para criar filtros de pesquisa em sua API Rest usando o Eloquent.
??
A biblioteca Eloquent Filter pode ser usada para criar padrões para critérios de pesquisa em modelos em seu projeto Laravel. A ideia é agregar filtros simplesmente passando os valores na carga útil da sua solicitação.
Para instalação, você deve usar o Composer. Execute o seguinte comando:
composer require laravellegends/eloquent-filter
A característica LaravelLegendsEloquentFilterConcernsHasFilter
pode ser usada em modelos que aplicarão os filtros de pesquisa.
use LaravelLegends EloquentFilter Concerns HasFilter ;
class User extends Model
{
use HasFilter ;
}
A característica HasFilter
fornece os métodos filter
e withFilter
.
Uma maneira simples de usar esta biblioteca em sua aplicação Laravel é chamar o método filter
antes de obter os resultados do seu modelo.
Exemplo:
class UsersController extends Controller
{
use App Models User ;
public function index ()
{
return User :: filter ()-> paginate ();
}
// or
public function index ()
{
return User :: latest ( ' id ' )-> filter ()-> paginate ();
}
// or
public function index ( Request $ request )
{
return User :: filter ( $ request )-> paginate ();
}
}
Você pode mostrar os resultados ao ligar /api/users?exact[id]=1
. A consulta sql "select * from users where (id = 1)"
será aplicada.
Nota: Mostre a sessão de regras para mais informações.
Outra forma é utilizar o filtro específico para um modelo. Você pode herdar a classe ModelFilter para criar um filtro personalizado para um modelo.
Para criar esta classe, você deve utilizar o comando php artisan make:filter
, conforme exemplo a seguir:
$ php artisan make:filter UserFilter
O comando acima irá gerar a seguinte classe:
namespace App Filters ;
use LaravelLegends EloquentFilter Filters ModelFilter ;
class UserFilter extends ModelFilter
{
public function getFilterables (): array
{
return [
' role_id ' => ' not_equal ' , // or ['not_equal']
' name ' => [ ' contains ' , ' starts_with ' ],
];
}
}
No controlador
use App Models User ;
use Illuminate Http Request ;
use LaravelLegends EloquentFilter Filter ;
class UsersController extends Controller
{
// api/users?starts_with[name]=Wallace¬_equal[role_id]=2
public function index ( Request $ request )
{
return User :: withFilter ( new UserFilter , $ request )
-> orderBy ( ' name ' )
-> get ();
}
}
O código acima será chamado internamente conforme exemplo a seguir:
User :: where ( function ( $ query ) {
$ query -> where ( ' name ' , ' LIKE ' , ' Wallace% ' );
$ query -> where ( ' role_id ' , ' <> ' , ' 2 ' );
})
-> orderBy ( ' name ' )
-> get ();
Esta biblioteca aplica filtros internamente com base em parâmetros de string de consulta com nomes de teclas especiais.
Veja todos os parâmetros a seguir:
O valor máximo de uma coluna. O url api/users?max[field]=100
é como um User::where('field', '<=', 100)
.
O valor mínimo de uma coluna. A url api/users?min[age]=33
é como User::where('age', '>=', 33)
.
Um termo de pesquisa contido em uma coluna. A url api/users?contains[name]=wallace
é como User::where('name', 'LIKE', '%wallace%')
.
Pesquise um valor de acordo com o conteúdo final da string. É semelhante a um LIKE
com valor %$value
value.
Filtre o campo quando o valor começar com um determinado valor. Um url api/users?starts_with[name]=brcontainer
Parece um User::where('name', 'LIKE', 'brcontainer%')
.
Pesquise por um valor exato do campo· Uma url api/users?exact[email][email protected]
Parece um User::where('name', '=', '[email protected]')
.
Filtre por relacionamento. Você pode usar o valor 0
ou 1
.
Exemplo:
A url api/users?has[posts]=1
é como User::has('posts')
A url api/users?has[posts]=0
é como User::doesntHave('posts')
Aplique WHERE IS NULL
ou WHERE IS NOT NULL
a uma consulta.
Exemplo:
A url api/users?is_null[cpf]=1
é como User::whereNull('cpf')
A url api/users?is_null[age]=0
é como User::whereNotNull('age')
Pesquisa quando uma coluna NÃO TEM os valores passados.
Exemplo:
A url api/users?not_in[role][]=1¬_in[role][]=2
é equivalente a User::whereNotIn('role', [1, 2])
Nota : Quando not_in[my_field]
for um array vazio, nenhuma ação será tomada.
Pesquisa quando uma coluna TEM os valores passados.
Exemplo:
A url api/users?in[role][]=10&in[role][]=20
soa como User::whereIn('role', [10, 20])
NOTA : Quando in[my_field]
for um array vazio, nenhuma ação será executada.
Pesquise por um valor máximo de um campo de data.
Uma url api/users?date_max[created_at]=2021-01-01
soa como User::whereDate('created_at', '<=', '2021-01-01')
Pesquise por um valor mínimo de um campo de data.
Exemplo:
Um url api/users?date_min[created_at]=2021-01-01
soa como User::whereDate('created_at', '>=', '2021-01-01')
Pesquisa por valor diferente foi aprovada. Se você usar em campo relacionado, o whereDoesntHave será aplicado.
Exemplo:
O URL api/users?not_equal[profile_id]=3
parece um
User :: where ( ' profile_id ' , ' <> ' , ' 3 ' );
O URL api/users?not_equal[roles.id]=1
parece um
User :: whereDoesntHave ( ' roles ' , fn ( $ query ) => $ query -> where ( ' id ' , ' = ' , 3 ));
O URL api/users?year_max[created_at]=2000
parece um
User :: whereYear ( ' created_at ' , ' <= ' , 2000 );
O URL api/users?year_min[created_at]=1998
parece um
User :: whereYear ( ' created_at ' , ' >= ' , 1998 );
O URL api/users?year_exact[created_at]=1998
parece um
User :: whereYear ( ' created_at ' , ' = ' , 1998 );
Você pode aplicar os filtros de pesquisa nos métodos de relacionamento definidos em seu modelo.
Por exemplo:
Modelo:
class User extends Model
{
use HasFilter ;
public function phones ()
{
return $ this -> hasMany ( Phone ::class, ' user_id ' );
}
}
Filtros:
class UserFilter extends ModelFilter
{
public function getFilterables (): array
{
return [
' id ' => [ ' exact ' , ' not_equal ' ],
' created_at ' => [ ' year_exact ' , ' date_max ' , ' date_min ' ],
' phones.number ' => [ ' contains ' ],
// or
' phones ' => new PhoneFilter ,
];
}
}
class PhoneFilter extends ModelFilter
{
public function getFilterables (): array
{
return [
' number ' => ' contains '
];
}
}
class UserController extends Controller
{
public function index ()
{
// api/users?not_in[role_id][]=1¬_in[role_id][]=3
// select * from users where (role_id NOT IN (1, 3))
return User :: withFilter ( new UserFilter )-> paginate ();
}
// Or, apply filter as nested query
public function index ()
{
// api/users?exact[role_id]=1
// select * from users where (role_id = 1)
return User :: where ( UserFilter :: toClosure ())-> paginate ();
}
// Or apply in your query as base condition
public function index ()
{
// api/users?exact[role_id]=1
// select * from users where role_id = 1
return User :: tap ( UserFilter :: toClosure ())-> paginate ();
}
}
No exemplo a seguir, o usuário será filtrado pelo telefone relacionado que contém o valor 55
.
A api/users?exact[phones.number]=55
é semelhante a:
User :: where ( function ( $ query ) {
$ query -> whereHas ( ' phones ' , function ( $ query ) {
$ query -> where ( ' number ' , ' = ' , ' 55 ' );
});
})-> paginate ();
Se você usar a biblioteca axios
, poderá usar as opções de params
para incluir os filtros acima.
Exemplo:
const api = axios . create ( {
baseURL : 'http://localhost:8000/api'
} ) ;
api . get ( 'users' , {
params : {
'in[role]' : [ 1 , 2 , 3 ] ,
'contains[name]' : 'Maxters' ,
'is_null[name]' : 0
}
} )