关于 laravel-query-builders
面向 Laravel 开发的技能,建议使用自定义 Eloquent 查询构建器代替本地作用域,涵盖类型安全、可组合的查询逻辑、模型注册、复用 Trait 和常见查询模式。
主要功能
- 01用自定义构建器替代本地作用域
- 02类型安全的嵌套关联查询
- 03可复用的查询 Trait
- 04在模型中注册构建器
- 05组合筛选与关联加载
适用场景
- 01在专用构建器中整理订单筛选
- 02为关联查询添加类型安全条件
- 03复用日期或状态查询逻辑
- 04加载关联模型并分页结果
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ leeovery/ agentic-skills --skill laravel-query-builders安装后在 Claude Code 中输入/laravel-query-builders确认已加载。
详细介绍
Laravel 查询构建器
始终使用自定义查询构建器,而不是本地作用域。
相关指南:
为什么优先选择自定义构建器,而不是作用域
❌ 不要使用本地作用域。
✅ 使用自定义查询构建器,因为它们具备以下优势:
- 类型提示更好 - IDE 自动补全更完善
- 嵌套查询类型安全 - 可在
whereHas()、orWhereHas()等方法中为闭包添加类型提示 - 组织更清晰 - 所有查询逻辑都集中在一个类中
- 组合性更强 - 更容易进行链式调用和组合
- 更易测试 - 可单独测试查询逻辑
基本构建器结构
<?php
declare(strict_types=1);
namespace App\Builders;
use App\Enums\OrderStatus;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
class OrderBuilder extends Builder
{
public function wherePending(): self
{
return $this->where('status', OrderStatus::Pending);
}
public function whereCompleted(): self
{
return $this->where('status', OrderStatus::Completed);
}
public function whereCustomer(User|int $customer): self
{
$customerId = $customer instanceof User ? $customer->id : $customer;
return $this->where('customer_id', $customerId);
}
public function whereTotalGreaterThan(int $amount): self
{
return $this->where('total', '>', $amount);
}
public function wherePlacedBetween(Carbon $start, Carbon $end): self
{
return $this->whereBetween('placed_at', [$start, $end]);
}
public function withRelated(): self
{
return $this->with(['customer', 'items.product', 'shipments']);
}
public function recent(): self
{
return $this->latest('placed_at');
}
}
类型安全的嵌套查询
为闭包添加类型提示,以便在关系查询中获得完整的 IDE 支持:
public function whereHasItems(array|string $productIds): self
{
return $this->whereHas('items', function (OrderItemBuilder $query) use ($productIds): void {
$query->whereIn('product_id', (array) $productIds);
});
}
用法:
Order::query()
->whereHas('items', function (OrderItemBuilder $query): void {
$query->whereActive() // Custom method - autocomplete works!
->whereProduct($id); // Full type safety!
})
->whereHas('customer', function (CustomerBuilder $query): void {
$query->whereVerified() // Custom method
->wherePremium(); // IDE knows all methods!
})
->get();
外部方法的 PHPDoc
为 Spatie 软件包或宏中的方法添加文档说明:
/**
* @method static OrderBuilder whereState(string $column, string|array $state)
* @method static OrderBuilder whereNotState(string $column, string|array $state)
*/
class OrderBuilder extends Builder
{
// ...
}
构建器 Trait
提取可复用的查询逻辑:
<?php
declare(strict_types=1);
namespace App\Builders\Concerns;
use Illuminate\Support\Arr;
trait HasProducts
{
public function whereHasProducts(array|string $productIds): self
{
return $this->whereHas('products', function ($query) use ($productIds): void {
$query->whereIn('id', Arr::wrap($productIds));
});
}
public function whereHasActiveProducts(): self
{
return $this->whereHas('products', function ($query): void {
$query->where('active', true);
});
}
}
在构建器中的用法:
class OrderBuilder extends Builder
{
use HasProducts;
// ...
}
在模型中注册构建器
首选:PHP Attribute(Laravel 12+)
use Illuminate\Database\Eloquent\Attributes\UseEloquentBuilder;
#[UseEloquentBuilder(OrderBuilder::class)]
class Order extends Model
{
// ...
}
备用方案:重写方法(Laravel 12 之前)
public function newEloquentBuilder($query): OrderBuilder
{
return new OrderBuilder($query);
}
用法示例
基本链式调用
Order::query()
->wherePending()
->whereTotalGreaterThan(10000)
->wherePlacedBetween(now()->subWeek(), now())
->withRelated()
->recent()
->paginate();
惰性迭代
Order::query()
->whereCompleted()
->lazyById()
->each(function (Order $order): void {
// Process order
});
复杂查询
$orders = Order::query()
->wherePending()
->whereCustomer($user)
->whereHasItems([$productId1, $productId2])
->wherePlacedBetween($startDate, $endDate)
->withRelated()
->get();
空构建器
始终创建构建器,即使初始内容为空——以便未来扩展:
<?php
declare(strict_types=1);
namespace App\Builders;
use Illuminate\Database\Eloquent\Builder;
class CustomerBuilder extends Builder
{
// Empty for now, but ready for future methods
}
常见构建器方法
状态筛选
public function whereActive(): self
{
return $this->where('status', 'active');
}
public function whereInactive(): self
{
return $this->where('status', 'inactive');
}
日期范围
public function whereCreatedAfter(Carbon $date): self
{
return $this->where('created_at', '>', $date);
}
public function whereCreatedToday(): self
{
return $this->whereDate('created_at', today());
}
用户/所有者筛选
public function whereUser(User|int $user): self
{
$userId = $user instanceof User ? $user->id : $user;
return $this->where('user_id', $userId);
}
关系加载
public function withFullRelations(): self
{
return $this->with([
'user',
'items.product',
'customer.address',
]);
}
构建器组织
app/Builders/
├── OrderBuilder.php
├── CustomerBuilder.php
├── ProductBuilder.php
└── Concerns/
├── HasProducts.php
├── HasDates.php
└── HasStatus.php
评论
支持 Markdown