در پروژه اخیر ما نیاز به یک جستجوی پیشرفته روی مدل های مختلف داشتیم. این جستجو فیلترهای زیادی را شامل می شد که نیازمند یک سیستم جستجوی منعطف و مقیاس پذیر بود. من تصمیم گرفتم برای این سیستم یک پکیج پیاده سازی کنم که شما می توانید آن را در گیت هاب مشاهده و در پروژهای خود استفاده کنید.
مشکل از اینجا شروع می شود که شما با مجموعه ای از فیلترها روبرو می شوید که برای اضافه کردن آنها به Query باید شرط های زیادی را بررسی کنید.
نوشتن شرط های زیاد حتما از خوانایی کد شما می کاهد و روند توسعه را کُند و پیچیده می کند. همچنین, شما از فیلتر ها و شرط هایی که نوشتید فقط می توانید در یک حوزه استفاده کنید و قابل استفاده مجدد نیز نخواهند بود.
شما باید کدهای خود را Refactor کنید!
برای رهایی از این مشکل باید کد خود را به روش Polymorphism برای جایگزین کردن شرط ها Refactor کنید.
برای آشنایی بیشتر این design pattern اینجا کلیک کنید.
فرض کنید شما نیاز دارید لیست کاربرانی را با پارامترهای درخواستی زیر دریافت کنید:
http://virgool.io/users?age_more_than=25&gender=male&has_published_post=true
پارامتر های درخواستی به صورت زیر خواهند بود:
[ 'age_more_than' => '25', 'gender' => 'male', 'has_published_post' => 'true', ]
در روش معمولی ما بصورت زیر فیلتر ها را اعمال میکنیم:
<?php namespace App\Http\Controllers; use App\User; use Illuminate\Http\Request; class UserController extends Controller { public function index(Request $request) { $users = User::where('is_active', true); if ($request->has('age_more_than')) { $users->where('age', '>', $request->age_more_than); } if ($request->has('gender')) { $users->where('gender', $request->gender); } if ($request->has('has_published_post')) { $users->where(function ($query) use ($request) { $query->whereHas('posts', function ($query) use ($request) { $query->where('is_published', $request->has_published_post); }); }); } return $users->get(); } }
در اینجا به ازای پارامتر های درخواستی, شرط هایی را برسی کردیم. همچنین با اضافه شدن پارامترهای درخواستی, ما باید شرط های دیگری را جهت بررسی و محدود کردن Query به تیکه کد بالا اضافه کنیم که تمیزی کد ما را از بین می برد.
بعد از نصب پکیج معرفی شده, تنها کافیست کد خود را به صورت زیر تغییر دهید:
<?php namespace App\Http\Controllers; use App\User; use Fouladgar\EloquentBuilder\EloquentBuilder; use Illuminate\Http\Request; class UserController extends Controller { public function index(Request $request) { $users = EloquentBuilder::to( User::class, $request->all() ); return $users->get(); } }
شما فقط کافیست مدل و لیست پارامترها را به متد to ارسال کنید و بعد از آن به ازای پارامترهای درخواستی که قرار است به Query اضافه شوند فیلتر تعریف کنیم.
به همین راحتی!
برای نمونه من یکی از فیلترهای مثال بالا را پیاده سازی میکنم.به مثال زیر دقت کنید:
<?php namespace App\EloquentFilters\User; use Fouladgar\EloquentBuilder\Support\Foundation\Contracts\Filter; use Illuminate\Database\Eloquent\Builder; class AgeMoreThanFilter implements Filter { /** * Apply the age condition to the query. * * @param Builder $builder * @param mixed $value * * @return Builder */ public function apply(Builder $builder, $value): Builder { return $builder->where('age', '>', $value); } }
برای مشاهده جزئیات بیشتر به آدرس پکیج در گیت هاب مراجعه کنید.
موفق باشید و ممنون بابت وقتی که گذاشتید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.