فیلتر کردن کوئریهای Eloquent با پکیج Filterable
خلاصهٔ کاملتر
تو این مقاله از Laravel News معرفی شده که Filterable که Abdalrhman Emad Saad ساخته، یه پکیج لاراوله که یه روش ساختارمند برای فیلتر کردن کوئریهای Eloquent میده. به جای اینکه توی کنترلر دستی کوئری بسازی، این پکیج از کلاسهای فیلتر اختصاصی و چند موتور تخصصی استفاده میکنه تا درخواستهای HTTP رو به کوئری دیتابیس نگاشت کنه. به گفتهٔ نویسنده، قوت اصلیش همین معماری ماژولار موتورهاشه که بهت اجازه میده استایل فیلترینگی رو انتخاب کنی که به فرانتاندت میخوره.
برای شروع کافیه trait به نام HasFilterable رو به مدلت اضافه کنی و یه کلاس فیلتر پیشفرض بهش bind کنی:
class Task extends Model
{
use HasFilterable;
protected $filterable = TaskFilter::class;
}بعدش توی کنترلر فقط Task::filter()->paginate() رو صدا میزنی و پکیج خودش پارامترهای درخواست رو تشخیص میده.
بخش اصلی کار همون چهار موتور توکاره که هرکدوم یه فرمت درخواست رو هندل میکنن. موتور Invokable کلیدهای درخواست رو به متدهای مشخص توی کلاس فیلترت نگاشت میکنه و از attributeهای PHP 8 برای کست، validation و authorization پشتیبانی میکنه. موتور Ruleset کوئریهای تخت فیلد-عملگر-مقدار رو هندل میکنه (مثل پیدا کردن آیتمهای پرموجودی). موتور Expression همینو گسترش میده تا با dot notation روی رابطههای عمیق Eloquent فیلتر بزنی، مثل فیلتر تیکتها بر اساس پلن اشتراک مشتری. موتور Tree هم درختهای تودرتوی AND/OR رو بهصورت JSON میگیره و بازگشتی به گروههای where و orWhere ترجمهشون میکنه.
موتور Invokable از attributeهای PHP 8 استفاده میکنه تا کارهای رایج مثل پاکسازی ورودی و validation رو مستقیم روی متدهای فیلتر تعریف کنی — مثلاً فیلدهای required یا دسترسی بر اساس نقش:
class TaskFilter extends Filterable
{
#[Cast('integer')]
#[In([1, 2, 3])]
protected function priority(Payload $payload)
{
return $this->builder->where('priority_level', $payload->value);
}
#[Authorize('manage-tasks')]
#[Required]
#[Date]
protected function due_date(Payload $payload)
{
return $this->builder->whereDate('deadline', '<=', $payload->value);
}
}یه سیستم کش داخلی هم داره که مخصوص خط لولهٔ فیلتره و از tagging، کش شرطی و scope کردن بر اساس کاربر یا tenant پشتیبانی میکنه؛ مثلاً میتونی نتایج رو فقط برای کاربرهای مهمون کش کنی یا با scopeByTenant موجودی هر شعبه رو جدا نگه داری. یه قابلیت auto-invalidation هم هست که موقع ساخت، آپدیت یا حذف مدل، تگهای کش مشخصی رو پاک میکنه.
نویسنده اشاره میکنه که پکیج چند دستور Artisan هم برای ساخت و دیباگ فیلترها داره، مثل filterable:make-filter برای ساخت scaffold، filterable:test برای تست با دادهٔ نمونه و filterable:inspect برای دیدن جزئیات یه کلاس فیلتر. نصبش با composer require kettasoft/filterableـه و به PHP 8.1 به بالا نیاز داره و از لاراول ۱۰ تا ۱۲ پشتیبانی میکنه.
نکات کلیدی:
- Filterable فیلتر کردن Eloquent رو از کنترلر میبره توی کلاسهای فیلتر اختصاصی و ساختارمند
- چهار موتور Invokable، Ruleset، Expression و Tree هر فرمت درخواستی رو از ساده تا درختهای تودرتوی AND/OR هندل میکنن
- موتور Expression با dot notation روی رابطههای عمیق Eloquent فیلتر میزنه
- attributeهای PHP 8 مثل Cast، In، Authorize و Required کست و validation و دسترسی رو روی خود متد تعریف میکنن
- سیستم کش داخلی با tagging، scope بر اساس tenant و auto-invalidation داره




