
在 Laravel 9 中,当子模型(如 Child)被更新或创建时,可通过 Eloquent 的 touches 属性自动触发关联父模型(如 Parent)的 updated_at 时间戳更新,无需手动调用 touch(),实现简洁、可维护的时间戳级联同步。
在 laravel 9 中,当子模型(如 child)被更新或创建时,可通过 eloquent 的 `touches` 属性自动触发关联父模型(如 parent)的 `updated_at` 时间戳更新,无需手动调用 `touch()`,实现简洁、可维护的时间戳级联同步。
Laravel 原生提供了优雅的机制来解决“子表变更需同步更新父表 updated_at”这一常见需求——即 时间戳触碰(Touching Timestamps)。其核心在于 protected $touches 属性,它声明了当前模型在保存时应自动“触碰”(即调用 touch())哪些关联关系,从而更新对应父模型的时间戳。
✅ 正确实现方式
首先,确保模型间已正确定义 Eloquent 关系。以题中结构为例:
// app/Models/Parent.php
class Parent extends Model
{
protected $table = 'parent_table';
}
// app/Models/Child.php
class Child extends Model
{
protected $table = 'child_table';
// 声明 belongsTo 关系,显式指定外键字段
public function parent()
{
return $this->belongsTo(Parent::class, 'foreign_parent_id');
}
// 关键:启用自动触碰父级时间戳
protected $touches = ['parent'];
}
✅ 效果说明:
- 当执行
$child->update(['name' => 'new name'])或$child->save()时,Laravel 不仅会更新child_table.updated_at,还会自动调用$child->parent->touch(),进而更新parent_table.updated_at; - 同样,通过
$parent->children()->create([...])创建新子记录时,父级updated_at也会被自动刷新(因create()触发模型保存流程,$touches生效); - 即使使用批量更新(如
Child::where(...)->update(...)),该机制不生效(因跳过模型事件和生命周期),此时仍需手动Parent::find($parentId)->touch()—— 但这是合理取舍,符合“模型层逻辑”的设计边界。
⚠️ 注意事项与最佳实践
-
关系名称必须与
$touches数组中的键完全一致:例如定义了public function parent(),则$touches = ['parent'];若关系名为owner(),则需写'owner'; -
外键字段名需在
belongsTo()中明确传递:题中为foreign_parent_id,不可依赖默认命名约定; -
不适用于
DB::table()或原生 SQL 操作:$touches是 Eloquent 模型特性,仅在通过模型实例操作时生效; -
避免循环触碰:若父模型也配置了
$touches = ['children'](反向触碰),将导致无限递归 —— Laravel 会抛出LogicException,务必单向配置(通常仅子触碰父); -
时间戳字段名可自定义:若父表使用非标准字段(如
last_modified),需在Parent模型中设置const UPDATED_AT = 'last_modified';,touch()会自动识别。
✅ 验证示例
// 更新子记录 → 自动同步父级 updated_at $child = Child::findOrFail(3); $child->content = 'Updated content'; $child->save(); // 此刻 Parent::find(1)->updated_at 被刷新 // 创建新子记录 → 父级 updated_at 同样更新 $parent = Parent::findOrFail(1); $parent->children()->create(['content' => 'New child']);
通过 protected $touches,你彻底告别散落在各处的 Parent::where(...)->touch() 调用,让时间戳同步逻辑集中、声明式、零侵入 —— 这正是 Laravel “约定优于配置”与 Eloquent 强大抽象能力的典型体现。











