- Filling up the QueryBuilder from user data. Key feature is safety: all data is under a validation.
- Profile-based approach limit access to the columns and operations.
composer require anourvalar/eloquent-request
Request
{
"filter": {
"created_at": {">": "2021-01-01"}
},
"sort": {
"created_at": "DESC"
}
}
Code
class UserController extends Controller
{
/**
* Profile
*/
protected $profile = [
'filter' => [
'created_at' => ['=', '!=', '<', '<=', '>', '>=', 'in', 'not-in'],
],
'sort' => ['created_at'],
];
/**
* Users list
*/
public function index(Request $request)
{
$users = \App::make(\AnourValar\EloquentRequest\Service::class)->buildBy(
\App\User::class,
$this->profile,
$request->input()
);
// Equals to:
// \App\User
// ::where('created_at', '>', '2021-01-01')
// ->orderBy('created_at', 'DESC')
// ->paginate($request->input('page'));
}
}
Request
{
"filter": {
"userPhones.phone_number": {"like": "1234"}
}
}
Code
class UserController extends Controller
{
/**
* Profile
*/
protected $profile = [
'filter' => [
'userPhones.phone_number' => ['like'],
],
];
/**
* Users list
*/
public function index(Request $request)
{
$users = \App::make(\AnourValar\EloquentRequest\Service::class)->buildBy(
\App\User::where('status', '=', 'active'), $this->profile, $request->input()
);
// Equals to:
// \App\User
// ::where('status', '=', 'active')
// ->whereHas('userPhones', function ($query)
// {
// $query->where('phone_number', 'like', '%1234%');
// })
// ->paginate($request->input('page'));
}
}
Code
class UserController extends Controller
{
/**
* Profile
*/
protected $profile = [
'options' => [
\AnourValar\EloquentRequest\Actions\PaginateAction::OPTION_SIMPLE_PAGINATE,
\AnourValar\EloquentRequest\Actions\PaginateAction::OPTION_PAGE_MAX => 20,
],
];
/**
* Users list
*/
public function indexAny()
{
$list = $this->buildBy(
\App\User::whereNotNull('email_verified_at')
);
// Equals to: \App\User::whereNotNull('email_verified_at')->simplePaginate($request->input('page'));
}
}
Code
class UserController extends Controller
{
use \AnourValar\EloquentRequest\ControllerTrait; // helper for quick usage
/**
* Profile
*/
protected $profile = [
'filter' => [
'created_at' => \AnourValar\EloquentRequest\Events\RequestBuiltEvent::PROFILE_FILTER_DATE, // preset
],
'ranges' => [
'created_at' => ['min' => '2018-01-01'], // filter's constrainment
],
'scope' => [
'customStuff', // Eloquent scope
],
'sort' => ['created_at'],
];
/**
* Users list
*/
public function indexAny()
{
$users = $this->buildBy(\App\User::where('status', '=', 'active'));
}
}
Code
$profile = [
'filter' => [
'id' => ['in'],
],
];
$request = [
'filter' => ['id' => ['in' => [1,2,3]]],
];
$collection = \EloquentRequest::buildBy(\App\User::class, $profile, $request);
Model Observer (saved, deleted):
\EloquentRequestFlat::sync(\App::make(\App\Drivers\ModelFlat::class), $model);
Migration (up):
\EloquentRequestFlat::createTable(\App::make(\App\Drivers\ModelFlat::class));
Migration (down):
\EloquentRequestFlat::dropTable(\App::make(\App\Drivers\ModelFlat::class));
Config:
'flat' => [
'shadow' => false,
],
Seeder:
if (! \EloquentRequestFlat::isActualTable($flatInterface)) {
\EloquentRequestFlat::createTable($flatInterface);
\EloquentRequestFlat::resync($flatInterface, \App\Model::class);
}
Config:
'flat' => [
'shadow' => true, // it's recommended to false when the structure is permanent
],
Seeder:
if (! \EloquentRequestFlat::isActualTable($flatInterface)) {
\EloquentRequestFlat::createTable($flatInterface);
}
After deploy:
if (\EloquentRequestFlat::shadow($flatInterface)) {
$closure = function ($flatInterface, $model) {
\DB::transaction(function () use ($flatInterface, $model) {
// Atomic lock (for sync):
// <...>
$this->syncSoft($flatInterface, $model->fresh());
});
};
\EloquentRequestFlat::resync($flatInterface, \App\Model::class, $closure);
\DB::transaction(function () use ($flatInterface) {
// Atomic lock (for sync):
// <...>
\EloquentRequestFlat::switchShadow($flatInterface);
});
}