Laravel如何为所有模型默认添加类似时间戳的登录用户自动填充字段
Laravel 全局自动填充 created_by/updated_by 字段实现方案
1. 数据库字段准备
首先创建迁移文件批量添加字段,执行命令:php artisan make:migration add_blame_columns_to_required_tables
打开生成的迁移文件,在up()方法中给所有需要的表添加两个字段:
public function up() { // 以posts、orders、comments三张表为例,按需替换为你自己的业务表 $tables = ['posts', 'orders', 'comments']; foreach ($tables as $table) { Schema::table($table, function (\Illuminate\Database\Schema\Blueprint $blueprint) { // 如果你要存用户姓名就用string类型,存用户ID就换成unsignedBigInteger $blueprint->string('created_by')->nullable(); $blueprint->string('updated_by')->nullable(); // 存ID的话可以额外加外键约束:$blueprint->foreign('created_by')->references('id')->on('users'); }); } }
执行迁移生效:php artisan migrate
2. 基础模型继承方案(你提到的思路,最适合全局统一使用)
在app/Models目录下新建BaseModel.php作为所有业务模型的父类:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Auth; class BaseModel extends Model { protected static function booted() { parent::booted(); // 模型创建时填充创建人和更新人 static::creating(function ($model) { if (Auth::check()) { $model->created_by = Auth::user()->name; $model->updated_by = Auth::user()->name; } }); // 模型更新时填充更新人 static::updating(function ($model) { if (Auth::check()) { $model->updated_by = Auth::user()->name; } }); } }
之后所有需要自动填充这两个字段的业务模型,把原来的继承Model改成继承BaseModel即可:
// 原来的写法 // class Post extends Model // 调整为 class Post extends BaseModel { // 原有模型代码保持不变,记得把created_by、updated_by加入$fillable protected $fillable = ['title', 'content', 'created_by', 'updated_by']; }
可选:Trait 实现方案(无需修改继承关系)
如果部分模型已经有自定义父类,不想调整继承结构,可以用Trait实现:
在app/Traits目录下新建Blameable.php:
<?php namespace App\Traits; use Illuminate\Support\Facades\Auth; trait Blameable { protected static function bootBlameable() { static::creating(function ($model) { if (Auth::check()) { $model->created_by = Auth::user()->name; $model->updated_by = Auth::user()->name; } }); static::updating(function ($model) { if (Auth::check()) { $model->updated_by = Auth::user()->name; } }); } }
在需要使用功能的模型中引入Trait即可:
use App\Traits\Blameable; class Post extends Model { use Blameable; // 其他模型代码,同样需要把两个字段加入$fillable }
注意事项
- 队列、命令行脚本等没有登录用户的场景下,
Auth::check()会返回false,不会填充字段,如果你需要这类场景下的默认值,可以在闭包中自行补充逻辑 - 两个字段必须加入对应模型的
$fillable允许批量赋值,或者将模型的$guarded属性设置为[],否则会抛出批量赋值错误
内容的提问来源于stack exchange,提问作者SusanCalvin
相关产品推荐
相关产品推荐

