laravel
🚀
vue
🚀
inertia
🚀
Nice way of doing filters in Laravel
I got a chunk of this idea from https://github.com/inertiajs/pingcrm
Basically I made a DTO:
<?php
namespace App\Data;
use Spatie\DataTransferObject\Attributes\CastWith;
use Spatie\DataTransferObject\Attributes\MapFrom;
class FilterDto extends \Spatie\DataTransferObject\DataTransferObject
{
#[MapFrom('sort')]
public string $sort = 'created_at';
#[MapFrom('order')]
public string $order = 'ASC';
#[MapFrom('type')]
public ?string $type;
#[MapFrom('active')]
#[CastWith(BoolCaster::class)]
public bool $active = false;
#[MapFrom('land_owner')]
#[CastWith(BoolCaster::class)]
public bool $land_owner = false;
#[MapFrom('land_owner_name')]
public ?string $land_owner_name;
#[MapFrom('flow_meter')]
#[CastWith(BoolCaster::class)]
public bool $flow_meter = false;
#[MapFrom('allow_gsa_contact')]
#[CastWith(BoolCaster::class)]
public bool $allow_gsa_contact = false;
#[MapFrom('has_well_complete_report')]
#[CastWith(BoolCaster::class)]
public bool $has_well_complete_report = false;
#[MapFrom('well_report_image')]
#[CastWith(BoolCaster::class)]
public bool $well_report_image = false;
#[MapFrom('well_report_doc')]
#[CastWith(BoolCaster::class)]
public ?bool $well_report_doc = false;
#[MapFrom('construction_date_month')]
public ?int $construction_date_month;
#[MapFrom('construction_date_year')]
public ?int $construction_date_year;
#[MapFrom('pump_hp')]
public ?int $pump_hp;
#[MapFrom('pump_type')]
public ?string $pump_type;
#[MapFrom('pump_manufacturer')]
public ?string $pump_manufacturer;
#[MapFrom('well_driller')]
public ?string $well_driller;
#[MapFrom('user_id')]
public ?int $user_id;
#[MapFrom('flow_meter_manufacturer')]
public ?string $flow_meter_manufacturer;
#[MapFrom('search')]
public ?string $search;
}
And then in the Controller I did this
public function wells()
{
$filters = request()->all();
$filters = new FilterDto($filters);
$users = User::get()->map(fn ($user) => [
'id' => $user->id,
'name' => $user->first_name.' '.$user->last_name,
]);
$types = Well::$types;
return inertia('Admin/Wells/Index', [
'wells' => Well::query()
->with(['user' => function ($query) {
$query->select('id', 'first_name', 'last_name', 'email');
}])
->filter($filters)
->paginate(50)
->withQueryString(),
'filters' => $filters,
'users' => $users,
'types' => $types,
'months' => $this->months(),
'years' => $this->years(),
]);
}
Then the model has a "Filter" method:
public function scopeFilter($query, FilterDto $filters)
{
return $query->when($filters->sort, function ($query) use ($filters) {
return $query->orderBy($filters->sort, $filters->order);
})->when($filters->search, function ($query) use ($filters) {
$like = '%'.$filters->search.'%';
return $query->where('lat', 'LIKE', $like)
->orWhere('apn', 'LIKE', $like)
->orWhere('gsa', 'LIKE', $like)
->orWhere('inactive_reason', 'LIKE', $like)
->orWhere('land_owner_name', 'LIKE', $like)
->orWhere('pump_hp', 'LIKE', $like)
->orWhere('pump_manufacturer', 'LIKE', $like)
->orWhere('pump_type', 'LIKE', $like)
->orWhere('well_driller', 'LIKE', $like)
->orWhere('flow_meter_type', 'LIKE', $like)
->orWhere('lng', 'LIKE', $like);
})->when($filters->construction_date_month, function ($query) use ($filters) {
return $query->where('construction_date_month', '=', $filters->construction_date_month);
})->when($filters->construction_date_year, function ($query) use ($filters) {
return $query->where('construction_date_year', '=', $filters->construction_date_year);
})->when($filters->type, function ($query) use ($filters) {
return $query->whereType($filters->type);
})->when($filters->active, function ($query) {
return $query->whereActive(1);
})->when($filters->flow_meter, function ($query) {
return $query->whereFlowMeter(1);
})->when($filters->has_well_complete_report, function ($query) {
return $query->whereHasWellCompleteReport(1);
})->when($filters->allow_gsa_contact, function ($query) {
return $query->whereAllowGsaContact(1);
})->when($filters->land_owner, function ($query) {
return $query->whereLandOwner(1);
})->when($filters->user_id, function ($query) use ($filters) {
return $query->whereUserId($filters->user_id);
});
}
Finally Inertia/Vue could send this
//table stuff here