关于 laravel-eloquent
面向 Laravel 开发者的 Laravel 13 Eloquent ORM 参考技能,重点说明以 PHP 8.3 Attributes 声明模型元数据,并涵盖查询、关系及模型生命周期操作。
主要功能
- 01以 PHP Attributes 声明模型元数据
- 02涵盖各类模型关系与预加载
- 03介绍作用域、事件和软删除
- 04提供集合、序列化与 API 资源指南
- 05涵盖事务、分页和批量操作
- 06包含查询调试与性能建议
适用场景
- 01将旧版模型迁移到 Laravel 13
- 02构建关联模型并避免 N+1 查询
- 03实现模型事件、软删除和 API 输出
- 04编写工厂测试并调优数据库查询
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ fusengine/ agents --skill laravel-eloquent安装后在 Claude Code 中输入/laravel-eloquent确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/accessors-mutators.mdaggregates.mdbatch-operations.mdcasts.mdcollections.mdeager-loading.mdevents-observers.mdfactories.mdlegacy-properties.mdmodels.mdpagination.mdperformance.mdquery-debugging.mdrelationships-advanced.mdrelationships-basic.mdrelationships-many-to-many.mdrelationships-polymorphic.mdresources.mdscopes.mdserialization.mdsoft-deletes.mdtransactions.mdreferences/templates/EagerLoadingExamples.php.mdFactory.php.mdModelBasic.php.mdModelCasts.php.mdModelRelationships.php.mdObserver.php.mdResource.php.md详细介绍
介绍 Laravel 13 Eloquent ORM,使用 PHP 8.3 Attributes 作为主要元数据机制(#[Table]、#[Fillable]、#[Hidden]、#[Visible]、#[Guarded]、#[Appends]、#[Touches]、#[Connection]、#[Refreshes]),同时提供用于向后兼容的旧版属性等效写法。涵盖所有关系类型(基本、多对多、高级、多态)、预加载、作用域、访问器/修改器、事件/观察者、软删除、集合、序列化、工厂、API 资源、事务、分页、聚合、批量操作,以及查询调试和性能优化。
Laravel Eloquent ORM(L13 — Attributes 优先)
Agent 工作流(强制)
在进行任何实现之前,并行启动 3 个 Agent,每个 Agent 调用一次,并指定 name:
- fuse-ai-pilot:explore-codebase - 检查现有模型,以及属性和 Attributes 的混用情况
- fuse-ai-pilot:research-expert - 通过 Context7 验证 Laravel 13 Eloquent 和 Attributes 文档
- mcp__context7__query-docs - 查询 Attribute 用法模式(#[Fillable]、#[Table]、#[Scope])
实现后,运行 fuse-ai-pilot:sniper 进行验证。
概览
Laravel 13 将 PHP 8.3 Attributes 提升为 Eloquent 模型的主要元数据机制。旧版属性($fillable、$hidden 等)仍受支持,以实现向后兼容,但不应与对应的 Attribute 混用。
| 功能 | Attribute(L13 主要用法) | 旧版属性 |
|---|---|---|
| 表名 | #[Table('users')] | protected $table |
| 批量赋值 | #[Fillable([...])] | protected $fillable |
| 隐藏 / 可见 | #[Hidden([...])] / #[Visible([...])] | protected $hidden / $visible |
| 受保护字段 | #[Guarded([...])] / #[Unguarded] | protected $guarded |
| 类型转换 | 无对应 Attribute — casts() 方法 | protected $casts |
| 附加属性 | #[Appends([...])] | protected $appends |
| 触碰时间戳 | #[Touches([...])] | protected $touches |
| 连接 | #[Connection('mysql')] | protected $connection |
| 主键 | #[Table(key: 'uuid', keyType: 'string', incrementing: false)] | $primaryKey / $keyType / $incrementing |
| 关闭时间戳 | #[WithoutTimestamps] | public $timestamps = false |
| 写入后刷新(13.33+) | #[Refreshes(['slug'])] | — |
关键规则
- 以 Attributes 为准 - 新代码使用
#[Fillable]、#[Hidden]、#[Table](类型转换仍放在casts()中) - 同一用途不得混用 Attribute 和属性(不得同时使用
#[Fillable]和$fillable) - 预加载关系 - 使用
with()防止 N+1 查询 - 不得在模型自身的
boot()/ Trait 的boot*()中使用new static()/new Model()- L13 中会抛出LogicException(不允许嵌套启动) - 在测试中使用工厂 - 不要硬编码测试数据
架构
app/Models/
├── User.php # #[Table], #[Fillable], #[Hidden] + casts()
├── Post.php # #[Connection], #[Appends], relationships
└── Concerns/
└── HasUuid.php # Reusable trait
→ 参见 templates/ModelBasic.php.md
参考指南
概念
- 迁移 L12→L13: legacy-properties.md
- 建模: models.md · casts.md · accessors-mutators.md · serialization.md · soft-deletes.md
- 关系: relationships-basic.md · relationships-many-to-many.md · relationships-advanced.md · relationships-polymorphic.md
- 查询: eager-loading.md · scopes.md · aggregates.md · pagination.md · batch-operations.md · query-debugging.md
- 生命周期 / 输出: events-observers.md · collections.md · resources.md · factories.md · transactions.md · performance.md
模板
| 模板 | 使用场景 |
|---|---|
| ModelBasic.php.md | 基于属性的模型 |
| ModelRelationships.php.md | 所有关系类型 |
| ModelCasts.php.md | casts() 和访问器 |
| Observer.php.md | 完整的观察者 |
| Factory.php.md | 带状态的工厂 |
| Resource.php.md | API 资源 |
| EagerLoadingExamples.php.md | 防止 N+1 |
快速参考
基于属性的模型(L13 主推)
use Illuminate\Database\Eloquent\Attributes\{Table, Fillable, Hidden};
use Illuminate\Database\Eloquent\Model;
#[Table('users')]
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
final class User extends Model
{
protected function casts(): array
{
return ['email_verified_at' => 'datetime', 'is_admin' => 'boolean'];
}
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
}
作用域(属性语法)
#[Scope]
protected function published(Builder $query): void
{
$query->whereNotNull('published_at');
}
// Usage: Post::published()->get();
预加载
$posts = Post::with('author')->get(); // 2 queries, not N+1
13.x 新增内容
#[Refreshes(['slug'])] // 13.33+: re-read generated columns after insert/update
final class Post extends Model {}
DB::transaction(function () use ($flight) {
$flight->refreshForUpdate(); // 13.27+: reload with a FOR UPDATE lock
});
→ 旧版 $fillable / $hidden 风格——参见 legacy-properties.md
最佳实践
应当
- 使用 PHP Attributes(
#[Table]、#[Fillable]、#[Hidden]等)声明元数据 - 模型类不被扩展时,使用
final - 使用
with()预加载 - 在测试中使用工厂
- 通过
casts()方法转换日期、数组和枚举(没有#[Casts]属性)
不应当
- 在同一模型上混用
#[Fillable]和$fillable(会产生冲突——应以单一来源为准) - 在模型自身的
boot()/ trait 的boot*()中实例化模型——L13 会抛出LogicException - 在循环中延迟加载关系(N+1)
- 在生产环境中使用
#[Unguarded] - 在访问器 / 修改器中执行查询
- 在模型中放置业务逻辑(请使用 Services/Actions)
评论
支持 Markdown