داشتم روی پروژه bugtracker کار می‌کردم و crud پروژه ها و باگ ها را درست کردم. نوبت رسید به پیاده سازی قابلیت جستجو.

این روز ها ویدئوهای لاراکست را زیاد نگاه می‌کنم. در یکی از آموزش ها با یک روش جالب برای پیاده سازی جستجو با استفاده از کوئری اسکوپ(query scope) آشنا شدم.

کوئری اسکوپ چیست؟

کوئری اسکوپ یک قابلیت در لاراول است برای اینکه بتوانیم بعضی کوئری ها را یک بار بنویسیم و با استفاده از یک متد آنها را صدا بزنیم و اجرا کنیم. اجازه بدهید یک نمونه آن را در پیاده سازی جستجو برای مدل Issue ببینیم.

در ساده ترین حالت در کنترلر این طوری جستجو را درست می‌کنیم:

//IssueController
public function index(Request $request)
    {
 
          $issues = Project::find($request->id)->issues()->latest()->
        
        when(request('search') ?? false,function($query){
            $query->where('title','LIKE','%' . request('search') . '%');
        }
        )->get();
        return view('issues.list', compact('issues'));
}

کد بالا می گوید هر وقت عبارت search در url وجود داشت، در جدول issues در ستون title آن را جستجو کن و نمایش بده.

با استفاده از query scope می توانیم کوئری که در کنترلر برای جستجو نوشتیم را منتقل کنیم به مدل و در یک متد بنویسیم.

من اسم این متد را می گذارم filter.

اسم متد به این شکل در مدل نوشته می شود: scope به اضافه اسم متد با حرف اول بزرگ. یعنی متد filter باید به صورت scopeFilter تعریف شود.

یک پارامتر هم به نام query$ باید داشته باشد. پارامتر بعدی مقداری است که می‌توانیم به متد پاس بدهیم. اینجا من عبارت جستجو شده را پاس می‌دهم.

داخل متد scopeFilter همان کوئری که برای search در controller نوشتیم را می‌نویسیم.

public function scopeFilter($query,$search){

        $query->when($search ?? false,function($q) use($search){
            $q->where('title','LIKE','%' . $search . '%');
        });
      
    }

در نهایت کد کنترلر را اینطوری بازنویسی می‌کنیم:

public function index(Request $request)
    {



        $issues = Project::find($request->id)->issues()->latest()->filter(request('search'))->get();

        return view('issues.list', compact('issues'));
    }

با این روش بدون اینکه به کنترلر کد دیگری اضافه کنیم می توانیم جستجو را برای ستون های مختلف جدول اجرا کنیم. تنها جایی که تغییر می کند کوئری نوشته شده در متد scopeFilter است.

کوئری اسکوپ ها جزییات بیشتری هم دارند. بهتر است نگاهی به مستندات لاراول بیاندازید.