ازاي تبني نظام فلترة عقاري احترافي باستخدام Laravel Eloquent
أهلاً بك يا صديقي المبرمج. أكيد جالك في يوم من الأيام "ريكويست" (Request) من عميل بيقولك: "عايز في موقع العقارات بتاعي، المستخدم يقدر يفلتر العقارات بالسعر، والمكان، وعدد الغرف، والمميزات زي حمام السباحة أو الجراج". الوهلة الأولى بتفكر في "أف" (if statements) كتير وورا بعض، وتلاقي الكود كبر منك وبقى صعب الصيانة. النهاردة هنشرح إزاي تعمل ده بأسلوب احترافي ونظيف باستخدام نظام الفلترة الديناميكي في لارفل (Laravel) مع إليوكوينت (Eloquent).
Table of contents [Show]
مشكلة الـ If Statements المتراكمة
أكبر غلطة بيقع فيها المبتدئ إنه بيكتب كود زي ده: لو السعر موجود فلتر، لو المكان موجود فلتر، وهكذا. النتيجة بتبقى كود مش مقروء (Spaghetti Code) وأداء سيء جداً لقاعدة البيانات. الحل الصح هو استخدام (Query Scopes) أو (Pipeline Pattern) عشان نفصل منطق الفلترة عن الكنترولر (Controller).
استخدام الـ Query Scopes لتنظيم الفلترة
في لارفل، الـ (Query Scopes) هي أفضل وسيلة عشان نكتب استعلامات ديناميكية (Dynamic Queries). بدلاً من كتابة كل شيء في الكنترولر، هننقل منطق الفلترة جوه الـ (Model). شوف المثال ده:
// Property.php (Model)
public function scopeFilter($query, array $filters)
{
$query->when($filters['price_min'] ?? null, function ($q, $price) {
$q->where('price', '>=', $price);
})->when($filters['price_max'] ?? null, function ($q, $price) {
$q->where('price', '<=', $price);
})->when($filters['city_id'] ?? null, function ($q, $cityId) {
$q->where('city_id', $cityId);
});
}
التعامل مع الفلاتر المعقدة والمميزات (Features)
العقارات دايماً بيكون ليها "مميزات" (Features) متخزنة في جدول تاني (Relationship Many-to-Many). عشان تفلتر العقارات اللي فيها "جراج" و "تكييف" مع بعض، لازم تستخدم whereHas بكفاءة. الكود ده بيضمن إننا بنفلتر العقارات اللي بتحتوي على كل المميزات المطلوبة مش بس واحدة منهم:
->when($filters['features'] ?? null, function ($q, $features) {
foreach ($features as $featureId) {
$q->whereHas('features', function ($subQuery) use ($featureId) {
$subQuery->where('feature_id', $featureId);
});
}
})
نصائح لتحسين الأداء (Performance Optimization)
لما الموقع بيكبر، الـ SQL Queries ممكن تبطأ. عشان كدة لازم تفتكر القواعد دي:
- استخدم Database Indexing على الأعمدة اللي بتفلتر بيها كتير زي (price, city_id, status).
- استخدم Eager Loading باستخدام (with) عشان تتجنب مشكلة الـ (N+1 Query Problem).
- لو الفلترة معقدة جداً، فكر في استخدام أدوات بحث متخصصة زي Laravel Scout مع Algolia أو Meilisearch.
خاتمة ونصيحة من أخ
تصميم نظام فلاتر متقدم مش مجرد كتابة كود بيشتغل، ده فن في التعامل مع البيانات (Data Handling). نصيحتي ليك يا بطل: لا تكتفي بإن الكود "يشتغل"، دور دايماً على "نظافة الكود" (Clean Code) وقابلية التوسع (Scalability). كل ما كان الكود بتاعك مفصول (Decoupled)، كل ما كان سهل عليك تعدل فيه أو تضيف ميزات جديدة في المستقبل من غير ما تكسر القديم.
استمر في التجربة، وجرب تقرأ في الـ (Pipeline Design Pattern) لأنه النقلة اللي جاية في تطوير مهاراتك في لارفل.