在 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=类别,类型,图像

相关推荐
声声codeGrandMaster4 分钟前
django之优化分页功能(利用参数共存及封装来实现)
数据库·后端·python·django
呼Lu噜38 分钟前
WPF-遵循MVVM框架创建图表的显示【保姆级】
前端·后端·wpf
bing_15842 分钟前
为什么选择 Spring Boot? 它是如何简化单个微服务的创建、配置和部署的?
spring boot·后端·微服务
学c真好玩1 小时前
Django创建的应用目录详细解释以及如何操作数据库自动创建表
后端·python·django
Asthenia04121 小时前
GenericObjectPool——重用你的对象
后端
Piper蛋窝1 小时前
Go 1.18 相比 Go 1.17 有哪些值得注意的改动?
后端
excel1 小时前
招幕技术人员
前端·javascript·后端
盖世英雄酱581362 小时前
什么是MCP
后端·程序员
小鸡脚来咯3 小时前
SpringBoot 常用注解通俗解释
java·spring boot·后端