在 Laravel 中创建过滤器

第 1 步 --- 安装和设置 Laravel AuthProject

第 2 步 --- 创建模型和关系

  • Products 产品
  • Product Category 产品分类
  • Product Type 产品类型
  • Images 图像

Product Model - 产品型号 -

php 复制代码
use App\Traits\UuidSet;  
use Illuminate\Database\Eloquent\Factories\HasFactory;  
use App\Http\Filter\QueryFilter;  
use Illuminate\Database\Eloquent\Builder;  
  
class Products extends Model  
{  
use UuidSet, HasFactory;  
protected $guarded = ['id' , 'created_at' , 'updated_at'];  
protected $fillable = [  
'status' ,  
'uuid_key',  
'type_id',  
'category_id',  
'title',  
'code' ,  
'description'  
];  
}  
//IT WILL BE RESPONSABLE TO QUERY THOSE FILTERS  
public function scopeFilter(Builder $builder, QueryFilter $filters) {  
return $filters->apply($builder);  
}  
  
// CATEGORY BELONGS TO PRODUCT  
public function Category(){  
return $this->belongsTo(ProductCategory::class , 'category_id');  
}  
  
// TYPE BELONGS TO PRODUCTS  
public function Type(){  
return $this->belongsTo(ProductType::class , 'type_id');  
}  
  
// A PRODUCT HAS IMAGES  
public function Images(){  
return $this->hasMany(ProductImages::class , 'propuct_id');  
}  
}

Product Category Model - 产品分类 型号 -

php 复制代码
use App\Traits\UuidSet;  
use Illuminate\Database\Eloquent\Factories\HasFactory;  
  
class ProductCategory extends Model  
{  
use UuidSet, HasFactory;  
  
  
protected $guarded = ['id' , 'created_at' , 'updated_at'];  
protected $fillable = [  
'title'  
];  
  
// RELATION SHIP  
public function props()  
{  
return $this->hasMany(Product::class , 'bath_id' );  
}  
}

Product Type Model - 产品类型 型号 -

php 复制代码
use App\Traits\UuidSet;  
use Illuminate\Database\Eloquent\Factories\HasFactory;  
  
class ProductType extends Model  
{  
use UuidSet, HasFactory;  
  
  
protected $guarded = ['id' , 'created_at' , 'updated_at'];  
protected $fillable = [  
'title'  
];  
  
// RELATION SHIP  
public function props()  
{  
return $this->hasMany(Product::class , 'bath_id' );  
}  
}

Image Model - 图像模型 -

php 复制代码
use App\Traits\UuidSet;  
use Illuminate\Database\Eloquent\Factories\HasFactory;  
  
class ProductImages extends Model  
{  
use UuidSet, HasFactory;  
  
  
protected $guarded = ['id' , 'created_at' , 'updated_at'];  
protected $fillable = [  
'uuid_key',  
'gallery_id',  
'image' ,  
'title' ,  
];  
  
public function Props() {  
return $this->belongsTo(Product::class ,'product_id' );  
}  
}

Create the Status Enum 创建 Status 枚举

php 复制代码
<?php  
  
namespace App\Classes\Enums\Property;  
  
use App\Traits\EnumToArray;  
  
enum PropStatusEnum:string  
{  
use EnumToArray;  
case ACTIVE = 'active';  
case INACTIVE = 'inactive';  
}

Step 3--- Create Filters 第 3 步 --- 创建过滤器

php 复制代码
class ProductFilter extends QueryFilter  
{  
// WHERE HAS THE CATEGORY ID  
public function category($id) {  
return $this->builder->where('category_id', $id);  
}  
// WHERE HAS THE TYPE ID  
public function type($id) {  
return $this->builder->where('type_id', $id);  
}  
// WHERE TITLE IS LIKE ( THE NAME OF THE PRODUCT)  
public function title($name)  
{  
$this->query->where('name', 'like', $name.'%');  
}  
  
// SEARCH THE PRODUCT CREATED AT BEFORE THE DATE  
public function beforeDate($date) {  
return $this->builder->whereDate('created_at' , '<' , $date );  
}  
  
// SEARCH THE PRODUCT CREATED AT AFTER THE DATE  
public function afterDate($date) {  
return $this->builder->whereDate('created_at' , '>' , $date );  
}  
  
// search the status enum  
public function status($value) {  
return $this->builder->where('status', $value);  
}  
  
// WHERE HAS MORE THAN IMAGES COUNTING, FOR EXAMPLE WE WANT TO GET PRODUCTS THAT HAS MORE THAN 3 IMAGES  
public function imageCount($imageNumber) {  
return $this->builder->withCount('Images')->having('images_count', '>', $imageNumber);  
}  
// WHERE HAS IMAGES ID  
public function images($id) {  
return $this->builder->WhereHas('Images' , function($query) use ($id) {  
return $query->where('id' , $id );  
});  
}

在这里,我们创建了一个可以在所有这些过滤器中使用的类。

php 复制代码
use Illuminate\Database\Eloquent\Builder;  
use Illuminate\Http\Request;  
  
class QueryFilter  
{  
  
protected $builder;  
protected $request;  
  
public function __construct(Request $request)  
{  
$this->request = $request;  
}  
  
protected function filter($arr) {  
foreach($arr as $key => $value) {  
if (method_exists($this, $key)) {  
$this->$key($value);  
}  
}  
  
return $this->builder;  
}  
  
public function apply(Builder $builder) {  
$this->builder = $builder;  
  
foreach($this->request->all() as $key => $value) {  
if (method_exists($this, $key)) {  
$this->$key($value);  
}  
}  
  
return $builder;  
}  
}

第 4 步 --- 创建资源

产品资源

php 复制代码
<?php  
  
namespace App\Http\Resources;  
  
use Illuminate\Http\Request;  
use Illuminate\Http\Resources\Json\JsonResource;  
  
class ProductResource extends JsonResource  
{  
/**  
* Transform the resource into an array.  
*  
* @return array<string, mixed>  
*/  
public function toArray(Request $request): array  
{  
  
return [  
'id' => $this->uuid_key,  
'status' => $this->status,  
'type' => new ProductTypeResource($this->whenLoaded('Type')),  
'category' => new ProductCategoryResource($this->whenLoaded('Category')),  
'images' => new ProductImageResource($this->whenLoaded('Images')),  
'title'=> $this->title,  
'code'=> $this->code,  
'description' $this->description  
];  
}  
}

产品分类资源 -

php 复制代码
<?php  
  
namespace App\Http\Resources;  
  
use Illuminate\Http\Request;  
use Illuminate\Http\Resources\Json\JsonResource;  
  
class ProductCategoryResource extends JsonResource  
{  
/**  
* Transform the resource into an array.  
*  
* @return array<string, mixed>  
*/  
public function toArray(Request $request): array  
{  
  
return [  
'id' => $this->uuid_key,  
'title'=> $this->title  
];  
}  
}

产品类型 资源 ---

php 复制代码
<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class ProductTypeResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {

         return [
             'id' => $this->uuid_key,
             'title'=> $this->title
            ];
     }
}

产品图片资源 -

php 复制代码
<?php  
  
namespace App\Http\Resources;  
  
use Illuminate\Http\Request;  
use Illuminate\Http\Resources\Json\JsonResource;  
  
class ProductImageResource extends JsonResource  
{  
/**  
* Transform the resource into an array.  
*  
* @return array<string, mixed>  
*/  
public function toArray(Request $request): array  
{  
  
return [  
'id' => $this->uuid_key,  
'title'=> $this->title,  
'image' => $this->image  
];  
}  
}

现在我们也可以为 Product Pagination 创建一个资源 -

php 复制代码
<?php  
  
namespace App\Http\Resources;  
  
use Illuminate\Http\Request;  
use Illuminate\Http\Resources\Json\JsonResource;  
  
class ProductPaginateResource extends JsonResource  
{  
/**  
* Transform the resource into an array.  
*  
* @return array<string, mixed>  
*/  
public function toArray(Request $request): array  
{  
return [  
"data" => ProductResource::collection($this->items()),  
'pagination' => [  
'total' => $this->total(),  
'per_page' => $this->perPage(),  
'current_page' => $this->currentPage(),  
'last_page' => $this->lastPage(),  
'from' => $this->firstItem(),  
'to' => $this->lastItem()  
]  
];  
}  
}

第 5 步 --- 创建过滤器

现在我们已经设置了这些过滤器。

它能够在 Product Controller 中创建方法

php 复制代码
use App\Traits\ApiResponse;  
class ProductController extends Controller  
{  
use ApiResponse;  
  
public function index(ProductFilter $filter,Request $request )  
{  
$props = Product::filter($filter)->with('Category', 'Type', 'Images')->paginate(40 ['*'], 'page', $request['page']);  
return $this->successResponse(new ProductPaginateResource($props));  
}  
}

Api Resonse Trait

php 复制代码
trait ApiResponse  
{  
public function successResponse($data = null, $code = Response::HTTP_OK)  
{  
return response()->json($data, $code);  
}  
}

Route::get('/products', [ProductController::class, 'index']);

第 6 步 --- 将 Include 添加到这些过滤器

我们可以创建在请求中包含这些模型的可能性 .以允许用户使用 includes or not 进行搜索。 在 QueryFilter 类中,我们可以进行更改并添加 include 方法-

php 复制代码
use Illuminate\Database\Eloquent\Builder;  
use Illuminate\Http\Request;  
  
class QueryFilter  
{  
  
protected $builder;  
protected $request;  
  
public function __construct(Request $request)  
{  
$this->request = $request;  
}  
  
protected function filter($arr) {  
foreach($arr as $key => $value) {  
if (method_exists($this, $key)) {  
$this->$key($value);  
}  
}  
  
return $this->builder;  
}  
// NOW ARE APPLING THE POSSIBILITY TO SEARCH AND BRING THE INCLUDE THAT WE WANT  
public function include($value) {  
// WE WILL MAKE THE REQUEST WITH THE INCLUDE SEPARATED BY COMA  
$sortAttributes = explode(',', $value);  
$list = collect([]);  
foreach($sortAttributes as $sortAttribute) {  
// IF DOES HAVE THE RELATION  
if (in_array($sortAttribute, $this->includeOption['relations'])) {  
// ADD THE INCLUDE  
$list->push($sortAttribute);  
}  
}  
$this->builder->with($list->all());  
}  
  
public function apply(Builder $builder) {  
$this->builder = $builder;  
  
foreach($this->request->all() as $key => $value) {  
if (method_exists($this, $key)) {  
$this->$key($value);  
}  
}  
  
return $builder;  
}  
}

现在在控制器上,我们可以删除搜索选项 --- 'Category', 'Type', 'Images' ( ->with('Category', 'Type', 'Images' ) ) 。

php 复制代码
use App\Traits\ApiResponse;  
class ProductController extends Controller  
{  
use ApiResponse;  
  
public function index(ProductFilter $filter,Request $request )  
{  
$props = Product::filter($filter)->paginate(40 ['*'], 'page', $request['page']);  
return $this->successResponse(new ProductPaginateResource($props));  
}  
}

现在我们可以搜索 -

{{APP_URL}}/api/products?category=1&type=1&imageCount=2&title=Dell Inspiron&include=Category,Type,Images

{{APP_URL}}/api/products?category=1&type=1&imageCount=2&title=Dell Inspiron&include=类别,类型,图像

相关推荐
Stark、2 小时前
C++入门day5-面向对象编程(终)
开发语言·c++·后端·学习方法
这河里吗l2 小时前
Java每日面试题(JVM)(day15)
java·开发语言·jvm·笔记·后端
AskHarries2 小时前
开发提效的工具tabby快速入门
spring boot·后端·openai
apz_end3 小时前
Python Flask网页开发基本框架
开发语言·后端·python·学习·flask·编程学习
gb42152873 小时前
spring中ApplicationContext的用法和作用举例
java·后端·spring
灯火不休ᝰ4 小时前
7--苍穹外卖-SpringBoot项目中套餐管理 详解(一)
java·spring boot·后端
xjjeffery4 小时前
网络基础概念和 socket 编程
linux·c语言·网络·后端
假装我不帅4 小时前
asp.net mvc 常用特性
后端·asp.net·mvc
小旋风-java6 小时前
springboot整合dwr
java·spring boot·后端·dwr
用户86178277365186 小时前
ELK 搭建 & 日志集成
java·后端·程序员